ユアマイスター株式会社エンジニアブログ

ユアマイスター株式会社のエンジニアが日々徒然。

CakePHP 3.4.7 にあげようとしたら思わぬところでハマったので、それが設定ファイルだったとしても変数名はちゃんと考えてつけましょう、という話。

こんばんは。ユアマイスターの星です。

弊社ではおなじみのCakePHPを使っているのですが、そのバージョンアップをしようとした時に、

うまくいかないところがあったので、これから3.4.7にあげようとしている方のためにも記録に残しておきます。

f:id:yourmystar_engineer:20170612215715p:plain

結論

  • バージョンアップ後、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’

github.com

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で上書きされてしまっていたのでした。

変数名をつける時には注意しましょう。

たとえそれが定数を規定する設定ファイルだったとしても、よく使いそうな(予約語っぽい言葉)はこんな事故を産みますので。