今日はバージョンアップ作業をしていときにFuelPHP(PHPのフレームワーク)から「Call to undefined method Error::shutdown_handler()」といわれた昔話をします。
この話はかなり脚色が入っています。 また、現在は当時の環境と全く異なっているため、昔書いたあすみめも(怪文)と睨めっこしながら思い出補正で記事を書いています。 空虚に向かって話す昔話として見てもらえると(っ'-')╮=͟͟͞͞🌹
前提&当時のゴール
N年前(0<N<100)、あるWebアプリケーションのアップデートが必要になりPJにアサインされました。 やらなきゃいけないことは山積みで、思い出せるだけでも以下がありました。
この環境はFuelPHPを使っており、バージョンも最新ではありませんでした。 技術スタックとしてFuelPHPを使い続けるかは議論の余地がありましたが、どうするかを決める優先度は低かったです。 (他があまりにも優先度高すぎるので...)
起きた問題
わたしがアサインされたのは「オンプレ環境からクラウド環境にのせる」ところです。 当時、確かコンテナにも載っていなかったので、その作業から始めたような気がします。
そして、もちろん(?)Composerも1系だったので、コンテナ化するときについでにComposerを2系していい感じにしちゃお、と考えました。 マルチステージビルドを利用して、以下のような感じでDockerfileを書きました。 ノリを伝えたいだけなので、めっちゃ適当に書いています。
# composer installをする FROM composer:2.x as vendor RUN composer install # Webアプリケーションを構築する FROM php:apache-buster COPY --from=vendor /app/vendor/ /app/vendor
また、composer.jsonは以下のようにpost-install-cmd
を指定していました。
これはFuelPHPフレームワーク側で最初から書いてあるものです。
{ "scripts": { "post-install-cmd": [ "php oil r install" ] } }
いざ、尋常に勝負!!ビルド!!!
PHP Fatal error: Uncaught Error: Call to undefined method Error::shutdown_handler() in /.../fuel/core/bootstrap.php:77 Stack trace: #0 [internal function]: {closure}() #1 {main} thrown in /.../fuel/core/bootstrap.php on line 77
・・・落ちる!!!
どうやらphp oil r install
で落ちているようでした。
エラーの内容でピンとくる人いますか・・・? 正統派PHPer(?)はこれを見ただけで「はぁ〜ん」ってなるんですかね。 ちなみに当時の私はマジで本当に何もわからず、めちゃくちゃ時間を使っていた覚えがありますw
なぜ起きたか
PHPは7系以上からErrorクラスができました。
class Error
はPHPのすべての内部エラーの規定クラスとして定義されています。
そして、当時のFuelPHPのバージョンではclass Error
が定義されています。
そうです!!Errorクラスが衝突していたのです!!💥
bootstrap.phpでFuelPHPのErrorクラスを参照したいが、コンテナ(実行環境)のPHPのバージョンを7以上としていたため、PHPの方のErrorクラスを参照してしまっているようでした。
解決方法
DockerfileのComposerバージョンを低く指定する
As I mentioned above, Composer 2.0 supports PHP 5.3+,
Composer2.0などでは、古いPHPのバージョンをサポートしているので、Dockerfileでこのバージョンを採用すればComposerの2系を採用することができます。
当時は解決法として正しかったかもしれませんが、現在この方法はまったくもって推奨されません。 このComposerのバージョンは脆弱性が見つかっているためです。
Composerのバージョン上げを後回しする
その時自分がもっていたタスクは「クラウドにのせること」だったため、当時は後回しにしました。 後回しというか、「Composerを1から2にする」というタスクを自然な位置に持っていきました。
そもそもPHPが5系なのも既にやるべき課題としてありました。 FuelPHPやPHPのバージョンアップと同時にComposerを2の最新まで上げることで自然に回避しました。
おわりに
息をするようにバージョンアップができる人間になりたい、ならなくちゃ、なるぞ