PHP7 で Laravel5 を試して出てきたエラー(その1)
少し前に投稿しましたが、Laraver5の勉強を兼ねて、こんなWebサイトの開発を行っています。
少しずつ動くようになってきたのですが、いろいろハマりどころもあったので、それらの原因や解決方法を備忘録代わりに書いていこうと思います。
まず、環境ですが、こんな感じです。
$ php -v
PHP 7.0.6 (cli) (built: Apr 28 2016 21:34:10) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
$ php artisan --version
Laravel Framework version 5.2.31
Windows上のPHPで軽く検証した後、AWSで開発しています。
それでは、ここから本題。
まず最初のエラーです
FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught ReflectionException: Class log does not exist in {MyApp DIRECTORY}/vendor/laravel/framework/src/Illuminate/Container/Container.php:738
logクラスが無いとか言われています。
Windowsで検証していた時は、こんな事は無かったです。
とりあえず、ぐぐってみました。
同じエラーで苦しんでいる人がいるようです。
色々書いてあります。
- Laraver5のアップデートによるバグを踏んでしまった?
⇒ composer update で解決? - Laraver5のアップデートでディレクトリ構成が色々変わった?
⇒ config ディレクトリを resources ディレクトリに移動? - laravel-develop から最新のソースを取得すると治る?
- config/app.php の文字列が問題?
⇒ 値をダブルコーテーションで囲えばOK? - phpのライブラリが足りない?
⇒ yum install を行う?
これらを一つ一つ試してみたのですが、どれもダメでした。
「現場百遍」という言葉があります。
事件の操作で、思い込みで見逃していたりする解決の糸口を探る事ですね。
開発において、バグやトラブルの解決のためには、現場の代わりにログがあります。
php.ini のコメントに下記の記載がありました。
; Common Values:
; E_ALL (Show all errors, warnings and notices including coding standards.)
; E_ALL & ~E_NOTICE (Show all errors, except for notices)
; E_ALL & ~E_NOTICE & ~E_STRICT (Show all errors, except for notices and coding standards warnings.)
; E_COMPILE_ERROR|E_RECOVERABLE_ERROR|E_ERROR|E_CORE_ERROR (Show only errors)
; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
PHP: Runtime Configuration - Manual
デフォルト値では、E_DEPRECATED や E_STRICT レベルのエラーは出力されないようです。
では、これを開発版に変更して
error_reporting = E_ALL
とします。
さて、ログを確認してみましょう。
#0: *28 FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught UnexpectedValueException: The stream or file "{MyApp DIRECTORY}/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in {MyApp DIRECTORY}/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:97
#0 {MyApp DIRECTORY}/vendor/monolog/monolog/src/Monolog/Handler/AbstractProcessingHandler.php(37): Monolog\Handler\StreamHandler->write(Array)
#1 {MyApp DIRECTORY}/vendor/monolog/monolog/src/Monolog/Logger.php(336): Monolog\Handler\AbstractProcessingHandler->handle(Array)
#2 {MyApp DIRECTORY}/vendor/monolog/monolog/src/Monolog/Logger.php(615): Monolog\Logger->addRecord(400, Object(UnexpectedValueException), Array)
#3 {MyApp DIRECTORY}/vendor/laravel/framework/src/Illuminate/Log/Writer.php(202): Monolog\Logger->error(Object(UnexpectedValueException), Array)
#4 {MyApp DIRECTORY}/vendor/laravel/framework/src/Illuminate/Log/Writer.php(113): Illuminate\Log\Writer->writeLog('error', Object(Un...
PHP message: PHP Fatal error: Uncaught UnexpectedValueException: The stream or file "{MyApp DIRECTORY}/storage/logs/laravel.log" could not be opened: failed to open stream: Permission denied in {MyApp DIRECTORY}/vendor/monolog/monolog/src/Monolog/Handler/StreamHandler.php:97
なんとわかりやすいエラーログでしょう。
(抜粋)
The stream or file "laravel.log" could not be opened: failed to open stream: Permission denied in "StreamHandler.php:97".
超直訳すると、こんな感じです。
(なんとなく伝わわらない・・・、けど気分を取り直して)
つまりですね、Logクラスが無いんじゃなくって、Log書き込めないんです。
具体的には、WebServerに nginx を使っていて、nginxユーサーで動いているのですが、
$ ls -l {MyAppDIRECTORY}storage/
drwxrwsrw- 3 ec2-user ec2-user 4096 Apr 27 22:01 app
drwxrwsrw- 5 ec2-user ec2-user 4096 Apr 27 22:01 framework
drwxrwsrw- 2 ec2-user ec2-user 4096 May 14 13:15 logs
となっていたんですね。
Laravelのログは、「storage/logs/laravel.log」に書き込まれるので、これじゃダメです。
ということで、
$ touch storage/logs/laravel.log
$ chmod 666 storage/logs/laravel.log
もしくは、
$ sudo chown nginx.nginx storage/logs
でも良いかもしれません。
一応、これで今回の問題は解決したのですが、その後、新たな問題が発生しこのログファイルに一杯エラーが書き込まれる事に。。。
まぁ、それはまた今度という事で。