PHP 8.0へのバージョンアップ時の注意点
TL;DR
- PHP 8.0.xへのバージョンアップ時にはエラーケースでの互換性確認も大事
- PHP 7.3.xからPHP 8.0.xへのバージョンアップでパフォーマンスが最大約1.5倍改善した
【2021新春福袋】 motorcycle 1976-1978 Hondamatic Automatic A CB750 CB750A Honda CB750自動ホンダミック1976-1978オートバイシートコード:D8564 ホンダCB750A シート seat D8564 CODE: シート
こんにちは。次世代システム研究室のT.Tです。
今年の6月に現在開発運用に携わっているサービスをPHP 8.0にバージョンアップしました。PHP 8.0ではJITを初め色々な新機能や仕様変更が取り込まれて、より使いやすくハイパフォーマンスな言語へと進化している印象で、早めにPHP 7.3から移行しておきたいと考えていました。一方PHP 7.3からバージョンアップすると下位互換性のない変更への対応が必要になり、バージョンアップ時に対応の不備があるとサービスに悪影響を及ぼす可能性もあります。
PHP 8.0のadapter デュアル2 "ヒッチレシーバーアダプターエクステンダー牽引4000LBS RVトラックSUV Dual 2" Hitch Receiver Adapter Extender Towing 4000lbs RV TRUCK SUVを確認してみると相当量のボリュームで、障子紙 おしゃれ モダン 小桜 夜桜 2枚組 縦1900mm SSSよりも多そうに見えます。無事にバージョンアップするのはなかなか大変そうですが、今回のバージョンアップ対応はローカル環境での検証から本番環境への導入、リリース後に発生した問題への対応等の一連の作業をベトナムラボのチームで担当してもらいました。本ブログではベトナムラボのチームが対応した内容を踏まえてPHP 7.3からPHP 8.0にバージョンアップする際の注意点を中心に、PHP 8.0についていくつかのトピックをご紹介します。
- シート Norton Commando Roadster 1970年代低いプロファイルカフェレーサーシートコードコードコードコード:L3150 Norton Commando Roadster 1970's low profile cafe racer seat CODE: L3150
- 2.本番環境リリース後に発生した問題
- ストラットバー・タワーバー マツダ323 BF用ホワイトラインフロントブレースストラットタワー(KSB606) Whiteline Front Brace Strut Tower FOR MAZDA 323 BF (KSB606)
- ポール・ジャブレ・エネエルミタージュ・ラ・シャペル ルージュ[2003]
- (まとめ)三栄産業 11号 帆布硬貨集金用巾着袋 ブルー KC2525SET5-09 1パック(5枚) 【×5セット】
富士フイルムBI(旧ゼロックス)ApeosPrint C320dw/Apeos C320z用トナーカートリッジ CT203535 イエロー【純正品】【翌営業日出荷】【送料無料】【SALE】
バージョンアップ対象のサービスのリグレッションテストを実施して問題のある箇所を改修しました。その内容についてご紹介します。
静的でないメソッドを静的に呼ぶことができる機能の削除
PHP 7.3では静的でないメソッドを静的に呼んでもstaticとして定義されているように振る舞いましたが、PHP 8.0ではFatal Errorが発生します。
class Hoge { public function fuga() { echo 'fuga'; } } Hoge::fuga();
【スーパーセール限定 15%OFF 209000円から177650円に!】ダイヤモンド ブレスレット 2.390カラット 18金ホワイトゴールド K18WG 定番 必需品 2カラットテニスブレス /白・透明(ホワイト)/アウトレット・新品/届10/ラックジュエル luckjewel/1点もの
オフセットを指定してアクセスするための波括弧のサポートの削除
PHP 7.3では配列のオフセットの指定に波括弧を利用できましたが、PHP 8.0ではFatal Errorが発生します。
$hoge = [1, 2, 3]; echo $hoge{0};
// PHP 7.3 1 // PHP 8.0 PHP Fatal error: Array and string offset access syntax with curly braces is no longer supported
mktime()とgmmktime()関数は少なくともひとつ引数が必要
PHP 7.3ではmktime()で現在時刻を取得できていましたが、PHP 8.0ではその用途での利用が出来なくなり、引数が必要になりました。サービスでは現在のタイムスタンプを取得するためにmktime関数を利用していたのでtime関数に置き換えました。
echo mktime();
// PHP 7.3 1633607686 // PHP 8.0 PHP Fatal error: Uncaught ArgumentCountError: mktime() expects at least 1 argument, 0 given
2.本番環境リリース後に発生した問題
PHP 8.0の下位非互換性のない変更に伴う改修は思ったより大分少なく済みました。しかし、本番環境にリリースした後に発生した問題があったためその点についてもご紹介します。
テスト漏れによる見落とし
静的でないメソッドを静的に呼ぶことができる機能の削除の影響はリリース前に把握できていましたが、リリース前のテストでは利用されていないコードと判断したコードが実際には使われていて、その部分でエラーが発生してしまいました。PHP 8.0とは直接関係ないですがバージョンアップ時には利用されているコードかどうかの判断には注意が必要です。
mktime関数からtime関数への移行ミス
PHP 8.0でmktime関数を現在のタイムスタンプを取得する用途で使えなくなったので一部time関数に置き換えましたが、mktime関数のままにしておくべき個所までtime関数に置き換えてしまったことでエラーが発生しました。コードを書き換えた後は必ず再テストしてエラーを検出しないといけません。
ValueErrorへの変更によるエラー
(業務用5セット) 【純正品】 Canon キャノン インクカートリッジ/トナーカートリッジ 【8048B001 BCI-355XXLPGBK ブラック】【送料無料】
try { ... curl_setopt(...); ... } catch (ErrorException $e) { if ($e->getMessage() === 'curl_setopt(): Curl option contains invalid characters (\0)') { ... } else { throw $e; } }
// PHP 7.3 PHP Warning 'yii\base\ErrorException' with message 'curl_setopt(): Curl option contains invalid characters (\0)' // PHP 8.0 Exception 'ValueError' with message 'curl_setopt(): cURL option must not contain any null bytes'PHP 8.0とYii 2との組み合わせによる問題かもしれませんが、エラーケースまでしっかりテストしないと検出できない問題なので悩ましい問題です。また、シート ブラットスタイル22 "1980-1983ホンダCB750C CB750カスタムカフェレーサーシートコードコード:E7020 Brat style 22" 1980-1983 Honda CB750C CB750 Custom cafe racer seat Code:E7020には特に記述がなく、TRUSCO 引出しユニット 553X307XH444 AW2X10 W VA-45BWN ( VA45BWN ) トラスコ中山(株)の内容にもValueErrorが追加されたという記述しかないので事前にエラーを検出するのは少し難しいです。
3.パフォーマンス検証
本番環境への導入前にPHP 7.3.18とPHP 8.0.2で実行時パフォーマンスをいくつか比較しました。そのうち最も改善が見られた、サービスで提供している更新系APIの比較結果をご紹介します。
パフォーマンスを計測したところ、更新系APIのスループットが約1.5倍になり、より高負荷な状況にも対応できるという結果が得られました。PHP 7.3.18はOPcacheを有効にして、PHP 8.0.2はOPcacheとJITを有効にし、jit_buffer_sizeにはサービス用のコードが全て収まるサイズを指定しています。VM一台にAPIコンテナを稼働させてgatlingで負荷を掛けて、そのスループットを比較しています。
PHP 7.3.18の結果
100qps/30秒 | 150qps/30秒 | 200qps/30秒 | |
APIコンテナ | 京焼 橋本城岳造 赤扇面文茶碗(共箱)【中古】【道】 宗sou メモリ: 約67MB |
CPU: 30-40% メモリ: 約67MB |
|
gatling | アメリカンイーグル レディース シャツ トップス AE Oversized Button-Up Beach Shirt White 平均応答時間: 8794ms 最小応答時間: 88ms 最大応答時間: 35500ms エラー: 3 (0%) |
スループット: 54.9/s 平均応答時間: 11340ms 最小応答時間: 0ms 最大応答時間: 60010ms エラー: 1326 (0%) |
150qpsで性能限界に達したため未計測 |
100qps/30秒 | 刀 かたな 雲シリーズ 赤雲 大刀 日本製 侍 日本刀 日本剣 模造刀 居合刀 サムライ 剣 武器 レプリカ 幕末時代 おもちゃ お土産 おみやげ プレゼント 外国人 喜ぶ 新選組 新撰組 時代劇 稽古 芝居 お芝居 小道具 玩具 | その他 (まとめ) リコー GXカートリッジ GC31Yイエロー Mサイズ 515746 1個 【×5セット】 ds-2222517 | |
トナーキットC1800 600103 マゼンタ【リコー】 | CPU: 50-70% メモリ: 約110MB |
CPU: 50-80% メモリ: 約110MB |
CPU: 50-80% メモリ: 約110MB |
gatling | スループット: 79.0/s 平均応答時間: 744ms 最小応答時間: 30ms 最大応答時間: 4469ms エラー: 0 (0%) |
スループット: 83.4/s 平均応答時間: 4216ms 最小応答時間: 113ms 最大応答時間: 31163ms エラー: 0 (0%) |
メルセデス ベンツ 純正 アクセサリー パフューム アトマイザー 交換用 リフィル BAMBOO MOOD A2238990200 平均応答時間: 8867ms 最小応答時間: 0ms 最大応答時間: 47052ms エラー: 911 (0%) |
CPU | メモリ |
2 core | 4GB |
zend_extension=opcache.so opcache.enable=1 opcache.enable_cli=1 opcache.jit_buffer_size=256M opcache.jit=1205
4.新機能の所感
PHP 8.0ではJIT以外にも名前付き引数やmatch式、null安全オペレータ等便利な機能が追加されてより簡潔なコーディングが出来そうな印象です。他にもアトリビュートが言語レベルでサポートされたりと開発者の意図を伝える機能も強化されて良い感じです。
5.まとめ
今回PHP 8.0.2にバージョンアップしましたが、PHP自体の問題で本番環境で発生した問題はなく、安心してメジャーバージョンを比較的早い段階で導入できるようになっていると感じました。それでもテストでの見落としを起因とした本番環境リリース後の障害は数件発生してしまい、無事にバージョンアップを完了することは出来ませんでした。バージョンアップは避けては通れないですが、本番環境での障害は出来れば無くしたいものです。今回発生した本番環境での障害にはエラーケースでの見落としを起因としたものもあり、そうしたケースは手動でのテストでは見つけるのが難しく、今後はバージョンアップも視野に入れてテストの自動化を進めていく必要がありそうです。
PHP 8.0にバージョンアップ出来てようやくサービス稼働も安定化できてきましたが、早くもPHP 8.1がリリースされそうです。次のバージョンアップはPHP 8.0のセキュリティサポートが切れる2年後を予定していますが、その頃には現在フレームワークとして使っているYii 2フレームワークの新しいバージョンのYii 3も使えるようになっているかもしれません。Yii 3への移行がどれくらい大変になるかは現時点では分かりませんし、状況によっては他のフレームワークや言語にリプレースする可能性もありそうです。バージョンアップ作業は大変ですがより良いサービスに繋げられるように引き続き様々な視点を持って研究に取り組んで行きたいと思います。
次世代システム研究室では、アプリケーション開発や設計を行うアーキテクトを募集しています。アプリケーション開発者の方、次世代システム研究室にご興味を持って頂ける方がいらっしゃいましたら、ぜひ CRG-040HBLK トナーカートリッジ040H ブラック キヤノン(Canon)用 リサイクルトナー 【リサイクル即納品】【回収無料】【安心保証付】【リユース品】 からご応募をお願いします。
皆さんのご応募をお待ちしています。