PHPをいじっていたら「HTTP ERROR 500」に遭遇して数時間の格闘の結果解決したのでそのときのメモを残しておきます。
HTTP ERROR 500とは
Wikipediaの「HTTPステータスコード」に記事によるとサーバー内部のエラーを表しているようです。ただし、今回は「Internal Server Error」とは出ていないのでサーバが落ちているわけではないのかなと思いましたが、コードが同じなので意味合いは同じなのかと思います。
原因一覧
インターネットで原因を調べてみると主に以下のものがあげられるようです。
・文法ミス
・ファイルのパーミッションミス
・ファイルの文字コードミス
・htaccessミス
・言語のバージョンミス
・アクセス過多
おおむね単純な文法ミスやローカル環境と本番環境の違いなどが考えられるのかなと思います。文法ミスの場合はphp.iniやソース冒頭に以下の設定をすることでエラーやワーニングを確認できるようになります。ただし、修正後はエラーやワーニングが表示されないよう戻しておくのが良心的です。(たまにPHPのワーニングらしきものが表示されているサイトを見かけます。忘れがちのため注意。)
<?php ini_set( 'display_errors', 1 ); ini_set( 'error_reporting', E_ALL );
また、環境を一切変更していないのに急に500が出たという場合はアクセス過多が原因かもしれないためアクセスログをチェックしてみてもよいと思います。
さくらサーバのエラーログのチェック
さくらサーバの例を取り上げると「アプリケーションの設定」→「アクセスログの設定」のページの「エラーログ」というリンクから見ることができます。
今回ここで確認はしましたが原因は見つけることができませんでした。ただし、ここで原因が見つかった場合はそのエラーが無くなるよう対処すればよいです。
メモリ不足が今回の原因
エラーログやブラウザ上に何もエラー表示が出なかったため特定に時間がかかりましたが、今回の原因は先ほど挙げたもののいずれでもなく単純にメモリ不足でした。処理の途中でデータベースから表を引っ張ってきて配列に収める箇所があったのですが、テーブルのレコード数がいつのまにか増えすぎたためその配列のサイズが大きくなり、落ちるようになっていたようです。データベースの呼び出し方法を工夫したところ正常に動作するようになりました。
まとめ・感想
今回原因は非常に単純ですが解決するのにとても時間をかけてしまいました。このようなことを起こさないためには将来的に不具合が起こらないように挙動を想像しながらプログラムを書き進めていく必要があるなと思いました。
また、500系に限らず原因となる候補をリストアップしていき一つ一つつぶしていくことが一番近道なのかなと改めて思いました。上記の原因一覧にはどれも当てはまらなさそうだなと思ったためメモリ不足という発想に至ることができたためです。