Syntax Error.

[Sy] nginx + php-fpm の環境で 500 エラー (Internal Server Error) が起きた場合の2つの調べ方

2017/10/11

nginx + php-fpm の環境で 500 エラーが起きた場合、php.ini の設定( display_errors = Off の場合)によってはちょっと原因が見えにくかったりします。その場合の調べ方について説明します。

500 エラーが発生。何が起きてるのか?

そもそも HTTPレスポンスコードが500の場合、これは Internal Server Error(内部サーバーエラー) というものになります。

すべてがそうではないですが、PHPを扱っている場合にこれが起きる場合、 PHPの構文エラー(Syntax Error)の可能性があります。

ということで、まずは調べ方を2つ説明します。

調べ方

調べ方は、以下の2つの方法があります。

  • 1. php.inidisplay_errorsOn にする
  • 2. php-fpm の エラーログを確認する(本番環境ではこちらを推奨)

では細かく見ていきます。

1. php.ini の display_errors を On にする

まず1つ目の方法。

PHP の初期設定では、エラーが起きた場合に ブラウザ上にエラーメッセージが表示されないようになっています

chromeだとこんな感じになります。

Internal Server Error (Chrome)

これじゃ、ちょっとどう調べてよいかさっぱりです。

それも当然。

エラーの手がかりとなる情報をむやみに外に出してしまうと、悪意のある人に攻撃のヒントを与えてしまうことになりかねません。 自分にわかりやすくするということは、一方で他人にもわかりやすくなりますよね。

この「エラーに関する情報を見えるようにするかどうか」を php.ini にある display_errors という設定項目で切り替えられるようになっています。

デフォルトだとこれが Off になっているので、これを On にしてあげるというのが、一つ目の方法です。

ただし、先程書いたように、 本番環境でこの設定を On にすることは控えましょう。

開発用の環境であれば、エラーがブラウザ上からすぐにわかるので、デバッグのしやすさを考えると便利です。

では設定を変更してみます。php.inivim などで開いて編集します。

$ sudo vim /etc/php.ini

以下の行を書き換えて、

display_errors = Off
↓
display_errors = On

php-fpm を再起動します。

$ sudo service php-fpm restart

やることは以上です。

もう一度問題のURLにアクセスすると、エラーメッセージが確認できるようになってるはずです。(エラー内容はエラーによって変わります)

この例だと、どうやら index.php の1行目でおかしなところに : が打たれてしまってるようです。

index.php を確認してみると、

<?php phpinfo():  <- 最後がセミコロンではなくコロンになってしまっている!

はい、原因がわかりました。

このようにエラーメッセージをブラウザ上に表示させることで、それが大事な手がかりとなって簡単に解決できる場合がほとんどです。

さっそく修正してみると、無事に phpinfo() の実行画面が表示されました。

ついでに、先ほどいじった display_errorsの設定値が確認できるので見てみると、 On になってるのがわかります。

これが Off の場合(デフォルト)では、こうなってます。

2. php-fpm の エラーログを確認する(本番環境ではこちらを推奨)

続いて2つ目です。こちらはサーバー上でのコマンド操作のみになるので、 外部にエラー内容を見せたくない場合に使えます。

nginxphp-fpm の環境だと、それぞれでエラーログが出力されていますが、 PHPの構文エラーの場合は php-fpm のログを確認する必要があります。

以下のコマンドを打ちます。php-fpm のバージョンによって、バージョンの数字の部分は異なります。

/var/log/ 配下は root の持ち物なので、sudo suroot に切り替えてます)

$ sudo su
# cd /var/log/php-fpm/7.0/
# ls
error.log  www-error.log

www-error.log の中身を見てみると、

# cat www-error.log
[11-Oct-2017 07:52:15 UTC] PHP Parse error:  syntax error, unexpected ':' in /var/www/test/index.php on line 1

と、ログを見ることで 先ほどブラウザ上に表示されていたエラーメッセージとまったく同じ内容が確認できることがわかります。

2つ目の調べ方は以上です。

ちなみに、 この時の nginx のエラーログ /var/log/nginx/error.log には特に何も出力されません。

そこでアクセスログ /var/log/nginx/access.log を見てみると、

xxx.xxx.xxx.xxx - - [11/Oct/2017:07:52:15 +0000] "GET / HTTP/1.1" 500 5 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36" "-"

というログが確認できます。途中にある 500 というのが HTTPレスポンスコードになるので、何かしらエラーが起きたということはわかりますが、それ以上の情報は得られません。

ひとこと

環境に応じて対処のしかたを変えると良いですね。

また、レスポンスコードによっては、nginx のエラーログを見る必要が有る場合もあるので、まぁとにかくエラーが起きたらどちらのログもチェックすると良いのではないかと。どのようにアクセスを捌いているのか勉強にもなりますし。