Slide 1

Slide 1 text

© RAKUS Co., Ltd. 1 PHP8.1で、リソースがオブジェクトに!? マイナーリリースの変更が レガシープロダクトに与えた影響 #phpkansai 2024/02/11 廣部知⽣

Slide 2

Slide 2 text

2 ⾃⼰紹介 21卒で株式会社ラクスに⼊社 PHPでMail Dealerの開発を⾏っている 『良いコード悪いコードで学ぶ設計⼊⾨』や 『ちょうぜつソフトウェア設計⼊⾨』で 設計を学ぶ⽇々…… 未だにスト6で戦いの螺旋を登り続けています (Act2はMR1700でフィニッシュ)

Slide 3

Slide 3 text

3           について メール共有管理システム 14年連続シェアNo.1(2009〜2022)※ 歴史は更に⻑く、2001年4⽉に販売開始 Laravelは2011年リリースなので、10歳年上 ※出典:ITR「ITR Market View:メール∕Webマーケティング市場2023」  メール処理市場:ベンダー別売上⾦額推移およびシェア2009-2022年度(予測値)

Slide 4

Slide 4 text

© RAKUS Co., Ltd. 4 PHPのアップデート、してますか?

Slide 5

Slide 5 text

5 Mail DealerのPHPアップデート戦略 ● 使⽤中のバージョンがEOLを迎えるときに 最新のバージョンへアップデートする戦略 ● 使⽤中のPHP8.0が 2023/11/26 にサポート終了予定 だったので当時最新だった PHP8.2 へ ● PHP8.1と、8.2の変更点を調べる

Slide 6

Slide 6 text

© RAKUS Co., Ltd. 6 PHP8.1

Slide 7

Slide 7 text

7 PHP8.1 の新機能! ● ENUM型! ● 読み取り専⽤プロパティ! ● 引数デフォルト値にNew! ● Finalクラス定数! などなど ※参考:https://www.php.net/releases/8.1/ja.php

Slide 8

Slide 8 text

8 PHP8.0 → PHP8.1への移⾏ 下位互換性のない変更 ● $GLOBALS へのアクセス制限 ● 継承したメソッド内で static 変数を使う ● 必須の引数の前に、デフォルト値を持つ引数を指定した場合 ● 内部クラスと戻り値の型の互換性 ● 新しいキーワード ● リソースからオブジェクトへの移⾏ ※参考:https://www.php.net/manual/ja/migration81.php

Slide 9

Slide 9 text

© RAKUS Co., Ltd. 9 リソースからオブジェクトへの移⾏? 🤔

Slide 10

Slide 10 text

10 リソースからオブジェクトへの移⾏ いくつかの リソース が、object に移⾏しました。 (´_ゝ`)フーン まあ⼤したことないだろ

Slide 11

Slide 11 text

11 リソースからオブジェクトへの移⾏ いくつかの リソース が、object に移⾏しました。 is_resource() 関数を使って戻り値をチェックしている コードは、false を返すことをチェックするコードに 置き換えるべきです。 ※参考:https://www.php.net/manual/ja/migration81.php

Slide 12

Slide 12 text

12 object移⾏によって⾏ったこと 今まで(PHP 8.0以前) $resource = pg_connect($connect_info) //接続成功時にresourceを返す is_resource($resource) //true これから(PHP8.1以降) $object = pg_connect($connect_info) //接続成功時にobjectを返す is_resource($object) //false

Slide 13

Slide 13 text

© RAKUS Co., Ltd. 13

Slide 14

Slide 14 text

14 PgSQL関数の変更による被害が甚⼤ DBへの接続判定や、SQLの実⾏結果の有無の判定に リソース変更が直撃

Slide 15

Slide 15 text

15 崩壊その1 DBへの接続処理判定に失敗し、SQLが実⾏されなくなる $connection = pg_connect($connect_info); // 接続成功時にobjectを返す if (is_resource($connection)){ // false判定されるように! $result = pg_query_params($connection, $query, $params) } else { throw new DbConnectException(); // 必ず接続エラーに }

Slide 16

Slide 16 text

16 崩壊その2 SQLの実⾏結果判定に失敗し、結果があるのに結果なしと判定 $result = pg_query_params($connection, $query, $params); if (is_resource($result)){ // false判定される! return pg_fetch_object($result) } else { return false; // 必ず結果なしになってしまう }

Slide 17

Slide 17 text

© RAKUS Co., Ltd. 17 どうして マイナーアップデートで こんな破壊的変更を 加えたんですか……?

Slide 18

Slide 18 text

18 とはいえ、修正はそんなに難しくない is_resource()の判定を、falseかどうかの判定に変えればOK $result = pg_query_params($connection, $query, $params); if ($result !== false){ return pg_fetch_object($result) } else { return false; } まあそのis_resource()の使⽤箇所を調べるのが ⼤変だったりはしたのですが……

Slide 19

Slide 19 text

© RAKUS Co., Ltd. 19 簡単に直っても マイナーアップデートで 破壊的変更を加えるのは やめてほしいです……

Slide 20

Slide 20 text

© RAKUS Co., Ltd. 20 時間があまるはず……

Slide 21

Slide 21 text

© RAKUS Co., Ltd. 21 PHP8.0→8.2で困ったことあげてきます

Slide 22

Slide 22 text

22 mb_detect_encodingの検出順位変更 タイトル通り 8.0と8.1で検出順位が変わる →今まで正常に受信できていたメール本⽂が  ⽂字化けして受信されるように 詳しくは「PHP8.2にバージョンアップしたら⽂字化けが発⽣して 道頓堀に⾶び込みたくなった話」にてやってました(過去形)

Slide 23

Slide 23 text

23 htmlspecialcharsのデフォルト値変更 以下の関数のデフォルト値が ENT_COMPAT → ENT_QUOTES | ENT_SUBSTITUTE に ● htmlspecialchars() ● htmlentities() ● htmlspecialchars_decode() ● html_entity_decode() ● get_html_translation_table()

Slide 24

Slide 24 text

24 htmlspecialcharsのデフォルト値変更 互換性維持のため、関数使⽤箇所を洗い出して ENT_COMPAT を明⽰的に指定していく……

Slide 25

Slide 25 text

25 PHPUnitのバージョンアップ(したかった……) バージョンアップに伴い、PHPUnit 10を利⽤できるように 現在使ってるPHPUnit 9も、いずれはサポート終了するので この機会に上げたい! →DBUnitがPHP10から⾮対応に Maildealerはレガシーなテストも多く、 DBと密結合したテストもざらにある →PHPUnitバージョンアップは先送りに……