PHPのバージョンを上げたらInternal Server Errorになる場合
PHP5.6のセキュリティサポートが2018年末に終わる関係であわててPHP7へ移行した人もいれば、あー…やんなきゃなぁ…と放置していて気がついたらもう8ヶ月経っていたというズボラマンもいると思います。
ぼくのことだ
いえね、一応言い訳をさせてもらうと、24時間止められないシステムなので(というか普通はWebってそういうものですね…)、ローカルネットワーク内で十分試してからアップしようと考えていたんですね。
そのため、ローカル環境ではPHP7系への対応は完了していて後はアップするだけ。
レンタルサーバー上でも管理ページでポチポチっとPHP5から7へ変更してボタンを押すだけだから、いつでも出来るわー、そのうちアクセスの少ない時間帯狙ってアップデートしよー……と思いつつすっかり忘れ……ごほん……様子を見ていた状況でした。
そんなぼくがちょっとした設定ミスでPHP7への切り替えに四苦八苦したので備忘録として顛末をメモっておこうと思います。
最近、VALUE-SERVERの調子がどうもよくない
以前、Webサイトの正常動作を定期的に監視するPHPスクリプトで書いたとおり、定期的にWebサイトが生きているか確認するスクリプトを1時間に1回自動実行しています。
そしてWebサイトが落ちていると判定されると、ぼくの元へメールが送信されるわけですが、これが最近週に1回くらい飛んでくるのです。いくら格安サーバーとはいえ、端的に言って異常事態です。
もちろん、その都度、サーバー会社へ連絡は入れるのですが、30分くらいで回復するため、「現象が確認できません」「ログを確認しましたがその時間帯にエラーは確認できませんでした」などとあしらわれてしまうばかり。
それでも淡々と落ちているときに報告を続けていたら、「高負荷の原因となっているユーザー様に対するアクセス制限をしました」という回答に変わってきました。
おぉ、とうとう重い腰を上げてくれたかっ!とちょっと感動しましたが、その後、数週間経っても状況は変わらず…。
同一サーバー上の別ドメインだと調子が良い謎
同一サーバー上に複数のドメインを設定して使っているのですが、同じサーバーなのにエラーメールが飛んでくるサイトと飛んでこないサイトがあることがわかりました。
最初はデータベースを疑いましたが、こちらは正常稼働。次にプログラム的なミスも疑いましたが、これも特に問題は見受けられない。
残る違いはPHPのバージョンだけ。
(ドメインごとにPHPのバージョンが変更できるので、既にPHP7へ移行済のサイトも一部ありました)
まさかPHPのバージョンが違うだけでアクセスできないほど重くなるとは考えづらいのですが、試しにテストサイトを作って、そちらをPHP7系で稼働させるとサイトが落ちることもなく正常になりました。
えぇぇ……マジか……。
PHP5のモジュールだけ何らかの異常が発生しているのか、セキュリティサポートが終了したことで、PHP5を狙ったDoS攻撃みたいなものが実行されているのか。
ともかく、PHP7へ切り替えればサイトが安定することがわかったため、稼働中のサイトをPHP7へ切り替えることに。
PHP7へ切り替えた途端、505 Internal Server Errorが発生
505 Internal Server Errorって、サーバーの設定が間違っている等、サーバー側に何ら可の致命的なエラーが発生しているときに表示されるエラーです。
おかしい。テスト用のサブドメインでは正常に動作していたのに本稼働用のサイトをPHP7にするとエラーが出るってどういうこと…。
人がたくさんアクセスしてきている時間帯だったので、アセりにアセりましたが、結果、.htaccessの問題であることが発覚。
CGIでは.htaccessのphp_flagが使えない
言われてみれば当たり前の話なのですが、.htaccessはApacheの設定であり、そこに記述するphp_valueやphp_flagはPHPのモジュール版でのみ有効な設定です。
■.htaccessの例
php_value mbstring.internal_encoding UTF-8
php_flag display_errors Off
php_flag short_open_tag On
そして、最近のPHPはセキュリティの観点から、モジュール版を使わず、CGIやFastCGIで動作させるのが一般的です。
VALUE-SERVERもその例に漏れないのですが、PHP5はモジュール版、PHP7系はCGI版、というちょっとややこしいことになっています。
つまり、モジュール版PHP5のために.htaccessへ記述していたphp_flag/php_valueが、PHP7(CGI)では無効なためエラーになっているというだけの話。
それならそうと言ってよー!エラーメッセージわかりづらいよー!w
そうとわかれば.htaccessからphp_flag/php_valueの設定を削除です。
PHPのCGI版では.user.iniを使う
ただ削除しただけではdisplay_errorsなどの設定が出来ないため、あらためて .user.ini というテキストファイルを作って、その中にPHPの設定を書いてあげる必要があります。
■.user.iniの例
display_errors = Off
short_open_tag = On
これは「PHPのエラーを表示しない」と「PHPの開始タグにショートタグを許す」という設定ですが、php.iniに書くときと全く同じ記述を.user.iniの中で書けばOK。そして有効にしたいディレクトリ下にこの.user.iniをFTPでほおりこめば設定完了です。
まとめ
- PHP5系はセキュリティサポートすら終了しているし、アタックを受けて重くなる可能性もあるため、とっととPHP7系へ移行しよう
- PHP5系でモジュール版を使っていた場合、高確率でPHP7ではCGI版またはFastCGI版を使うことになる。
- CGI版PHPでは.htaccessによるphp_flag/php_valueの設定は有効にならないため、.user.iniを使おう。
といったところでしょうか。
こうして書いてみると当たり前な話ですが、現在進行系で絶賛公開中のWebページで「505 Internal Server Error」を出してしまうとブラウザ画面と一緒に自分の頭の中も真っ白になりがちです。
ぼくと同じような凡ミス(.htaccessの変更忘れ)をされないようご注意ください。