こんばんは。ユアマイスターの星です。
弊社ではおなじみのCakePHPを使っているのですが、そのバージョンアップをしようとした時に、
うまくいかないところがあったので、これから3.4.7にあげようとしている方のためにも記録に残しておきます。
結論
- バージョンアップ後、500エラーが発生し画面が何も表示されないという事象が発生
- 3.4.7 で新設された
ServerRequestFactoryクラス内にあるextract関数により、config内に指定していた変数とServerRequestFactoryクラス内の変数名が衝突 - configの配列のキー名は安易に名付けるのはやめよう
諸悪の根源
The ServerRequestFactory is responsible for:
- Building a request from the SAPI super globals.
- Extracting the base and webroot directories for backwards compatibility with the CakeRequest.
- Updating the request path to reflect only the application’s ‘virtual path’
PSR-7準拠のために生まれたクラスとのことですが、その産声が小さすぎて完全に盲点でした。
調査の流れ
意気揚々とcomposer updateをやってバージョンアップを試みたら、検証環境でどうも動かない。。。
エラーログをみてみると下記のような記述。
Error: Fatal Error (256): [InvalidArgumentException] Invalid data type, must be an array or \ArrayAccess instance.
#0 /var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php(159): Cake\Utility\Hash::get('xxxxxxxxxxx....', 'PHP_SELF')
#1 /var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php(92): Cake\Http\ServerRequestFactory::getBase(Object(Zend\Diactoros\Uri), Array)
#2 /var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php(76): Cake\Http\ServerRequestFactory::marshalUriFromServer(Array, Array)
#3 /var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php(42): Cake\Http\ServerRequestFactory::createUri(Array)
#4 /var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Http/ServerRequest.php(231): Cake\Http\ServerRequestFactory::fromGlobals()
#5 /var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php(118): Cake\Http\ServerRequest::createFromGlobals()
#6 /var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Error/ExceptionRender in [/var/www/yourmystar.jp/vendor/cakephp/cakephp/src/Error/ErrorHandler.php, line 149]
'xxxxxxxxxxx....'のところは、$serverという変数であり、本当はArrayのはずなのに、Arrayじゃないのが入っていると怒られている。
ServerRequestFactory.phpを1行ずつデバッグしていくと、下記のコードの前後で$serverがArrayからStringに・・・
$config = Configure::read('App');
extract($config);
ファッツ?
プロジェクトの設定ファイルを見直すと、いました。'server'が。。。
'App' => [
'server' => 'hogehogehogehoge'
]
この設定とextract($config)があいまって、結果的に$serverが衝突して、Stringで上書きされてしまっていたのでした。
変数名をつける時には注意しましょう。
たとえそれが定数を規定する設定ファイルだったとしても、よく使いそうな(予約語っぽい言葉)はこんな事故を産みますので。