Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
PHPのバージョンアップ時にも役立ったAST
Search
Atsushi Matsuo
February 22, 2025
Programming
0
110
PHPのバージョンアップ時にも役立ったAST
2025-02-22 PHPカンファレンス名古屋2025 レギュラートーク資料
https://fortee.jp/phpcon-nagoya-2025
Atsushi Matsuo
February 22, 2025
Tweet
Share
More Decks by Atsushi Matsuo
See All by Atsushi Matsuo
OSSの開発や貢献時に役立つRFC
matsuo_atsushi
0
160
PHPの開発に貢献する4つの方法
matsuo_atsushi
0
360
Other Decks in Programming
See All in Programming
ARA Ansible for the teams
kksat
0
150
XStateを用いた堅牢なReact Components設計~複雑なClient Stateをシンプルに~ @React Tokyo ミートアップ #2
kfurusho
1
900
一休.com のログイン体験を支える技術 〜Web Components x Vue.js 活用事例と最適化について〜
atsumim
0
450
Spring gRPC について / About Spring gRPC
mackey0225
0
220
Grafana Loki によるサーバログのコスト削減
mot_techtalk
1
130
Boost Performance and Developer Productivity with Jakarta EE 11
ivargrimstad
0
230
Grafana Cloudとソラカメ
devoc
0
170
Software Architecture
hschwentner
6
2.1k
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.2k
Pulsar2 を雰囲気で使ってみよう
anoken
0
240
JavaScriptツール群「UnJS」を5分で一気に駆け巡る!
k1tikurisu
9
1.8k
なぜイベント駆動が必要なのか - CQRS/ESで解く複雑系システムの課題 -
j5ik2o
10
3.6k
Featured
See All Featured
Done Done
chrislema
182
16k
Build The Right Thing And Hit Your Dates
maggiecrowley
34
2.5k
Docker and Python
trallard
44
3.3k
How STYLIGHT went responsive
nonsquared
98
5.4k
The World Runs on Bad Software
bkeepers
PRO
67
11k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
233
17k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.4k
Learning to Love Humans: Emotional Interface Design
aarron
273
40k
Navigating Team Friction
lara
183
15k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2.1k
Building Flexible Design Systems
yeseniaperezcruz
328
38k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
630
Transcript
PHPのバージョンアップ時にも 役立ったAST 2025年2月22日 PHPカンファレンス名古屋2025 サイボウズ株式会社 松尾篤 1
PHPのバージョンアップ時にも役立ったAST トークの概要 はじめに • 勉強会で学んだことが実際の業務に役立った事例を紹介 • AST(抽象構文木、Abstract Syntax Treeの略)がPHP 8.1からPHP
8.2に バージョンアップした際の作業の一部で役立った事例 • ASTのハッシュ値に差分がないことを確認することで大幅にテスト工数を削減 2
PHPのバージョンアップ時にも役立ったAST 今回の話題 はじめに • PHPのリリースサイクルとバージョンアップの必要性 • PHPのバージョンアップ時に参照する移行ガイド • バージョンアップ時に挙動が変わらない根拠としてASTに着目 •
PHPでASTを取得およびそのハッシュ値を比較する方法 • ASTのハッシュ値を確認する際に留意する点 3
PHPのバージョンアップ時にも役立ったAST 自己紹介 はじめに 松尾篤 • PHP使用歴:約20年 • PHPを使った開発歴は約17年 • 2023年4月にGaroon開発チームに加入
• Garoonのセキュリティを維持するYukimiチームの紹介 https://blog.cybozu.io/entry/2023/10/04/101916 • 過去にコントリビュートしたことがあるOSS(抜粋) • PHP Debug Bar • Smarty • Goss • mod_python • Serverspec 4
PHPのリリースサイクルと バージョンアップの必要性 5
PHPのバージョンアップ時にも役立ったAST PHPのリリースサイクル PHPのリリースサイクルとバージョンアップの必要性 • 年に1回新しいバージョンが公開 • 2年間のアクティブサポート期間 • リリースされてから不具合やセキュリティの問題が修正される •
アクティブサポート期間の後に2年間のセキュリティサポート期間 • 重要なセキュリティ問題のみが修正される 6
PHPのバージョンアップ時にも役立ったAST もしもバージョンアップを行わなかったら PHPのリリースサイクルとバージョンアップの必要性 • PHPのセキュリティサポート期間の終了を迎えることになる • PHPに起因する不具合やセキュリティ脆弱性に対応できなくなる • 深刻なセキュリティ脆弱性がPHPに見つかって製品に重大な影響を与えて しまうような問題が出てきた場合にユーザーが危険な状況に陥ってしまう
• サービスやビジネスの継続に影響を与えてしまう恐れも 7
PHPのバージョンアップ時にも役立ったAST セキュリティのためにもバージョンアップは必要 PHPのリリースサイクルとバージョンアップの必要性 • セキュリティに対するリスクマネジメントは重要な経営課題の1つ • 最新のセキュリティ更新をすぐに取り込める状態を保つことはとても重要 • 日頃から製品で使用しているソフトウェアやライブラリを更新できる状態 や体制を整えておくことが大事
8
PHPのバージョンアップ時にも役立ったAST Garoon開発チームが過去のバージョンアップ時に直面した課題たち PHPのリリースサイクルとバージョンアップの必要性 • PHP 8.0:比較演算子の挙動変更 20年ものの巨大レガシープロダクトをPHP 8.0にアップデートした際の対策と得られた知見 by 赤間
仁志 https://speakerdeck.com/akamah/20nian-mononoju-da-regasipurodakutowo-php-8-dot-0niatupudetositaji-nodui-ce-tode-raretazhi-jian • PHP 8.1:mb_detect_encoding()の仕様変更 Garoon開発チームではPHP8.1の仕様変更とどう向き合ってきたのか by 千葉 泰理(ぱくとま) https://speakerdeck.com/pakutoma/how-we-have-responded-to-the-php-8-dot-1-mbstring-specification-changes • PHP 8.2:動的プロパティの非推奨化 PHP 9 に備えよ - 動的プロパティ、どうすればいぃ? by 荒瀬 泰輔 https://speakerdeck.com/taisukearase/php-9-nibei-eyo-dong-de-puropatei-dousurebaii 9
PHPのバージョンアップ時に 参照する移行ガイド 10
PHPのバージョンアップ時にも役立ったAST PHPをバージョンアップする前に PHPのバージョンアップ時に参照する移行ガイド • 移行ガイドを必ず確認 • PHP 8.2の場合:https://www.php.net/manual/ja/migration82.php • 新機能だけでなく推奨されなくなる機能や下位互換性のない変更点も記載
• 移行ガイドに記載されている内容に基づいて製品への影響がないか調査 11
PHPのバージョンアップ時にも役立ったAST PHP 8.2で推奨されなくなる機能 PHPのバージョンアップ時に参照する移行ガイド • https://www.php.net/manual/ja/migration82.deprecated.php より • 動的なプロパティの利用 •
部分的にしかサポートされていない callable • ”${var}” / “${expr}” 形式の、文字列への値の埋め込み • 'テキストエンコーディング' QPrint, Base64, Uuencode, HTML-ENTITIES • 内部メソッド SplFileInfo::_bad_state_ex() • utf8_encode() と utf8_decode() 12
PHPのバージョンアップ時にも役立ったAST 製品への影響が特に大きかった推奨されなくなる機能 PHPのバージョンアップ時に参照する移行ガイド • 動的なプロパティの利用 • ”${var}” / “${expr}” 形式の、文字列への値の埋め込み
13
PHPのバージョンアップ時にも役立ったAST ”${var}” / “${expr}” 形式の、文字列への値の埋め込み PHPのバージョンアップ時に参照する移行ガイド • “${var}”や“${expr}”といった形式での書き方が推奨されなくなった • "$var"、"{$var}"および"{${expr}}"といった形式で今後は書いていく
必要がある 14
PHPのバージョンアップ時にも役立ったAST ”${var}” / “${expr}” 形式の、文字列への値の埋め込み PHPのバージョンアップ時に参照する移行ガイド • PHP 9.0ではサポートされなくなる見通し •
https://wiki.php.net/rfc/deprecate_dollar_brace_string_interpolation 15
PHPのバージョンアップ時にも役立ったAST ”${var}” / “${expr}” 形式の、文字列への値の埋め込み PHPのバージョンアップ時に参照する移行ガイド • PHPStanで検出できなかった • https://github.com/phpstan/phpstan/issues/8744
16
PHPのバージョンアップ時にも役立ったAST 大量に見つかった変更すべき箇所 PHPのバージョンアップ時に参照する移行ガイド • PHPスクリプトのソースコードだけでも120万行以上ある製品 • 事前の調査で「“${var}” / “${expr}” 形式の、文字列への値の埋め込
み」だけでも434箇所変更すべき箇所が見つかっていた • PHP 8.2でPhanを使って検出(Issue Type : PhanDeprecatedEncapsVar) 17
PHPのバージョンアップ時にも役立ったAST 品質保証やテスト戦略をどうするべきかという課題に直面 PHPのバージョンアップ時に参照する移行ガイド • 大量に見つかった変更すべき箇所のソースコードを変更した場合に挙動が 変わらないように品質をどう担保するか • 変更する箇所すべてに対して1箇所ずつ細かくテストするのは手間や期間 を考えると現実的に無理 •
テスト工数を抑えられるような良い方法はないか思案 18
バージョンアップ時に 挙動が変わらない根拠としてASTに着目 19
PHPのバージョンアップ時にも役立ったAST AST バージョンアップ時に挙動が変わらない根拠としてASTに着目 • Abstract Syntax Treeの略 • 抽象構文木 •
ソースコードの構造をツリー状に表現したもの • ソースコードの解析や変換に活用できる 20
PHPのバージョンアップ時にも役立ったAST きっかけはPHP勉強会@東京 バージョンアップ時に挙動が変わらない根拠としてASTに着目 • PHP 8.2にバージョンアップする際の「"${var}" / "${expr}" 形式の、 文字列への値の埋め込み」についてはASTを活用できることに気づく
• 2023年11月に開催された「第158回 PHP勉強会@東京」で金城さんの ASTに関する発表を聞いたことがきっかけ 21 金城さんのASTに関する発表スライドより
PHPのバージョンアップ時にも役立ったAST ASTのハッシュ値が同じならプログラムの変更前後で差分がないと判断可能 バージョンアップ時に挙動が変わらない根拠としてASTに着目 • 第158回 PHP勉強会@東京における金城さんのASTに関する発表 • プログラムの本質的構造を示すASTのハッシュ値が同じであればプログラムの 変更前と変更後の間に差分がないと判断できるという内容の発表 •
https://speakerdeck.com/o0h/php-ast-check-diff 22 金城さんのASTに関する発表スライドより
PHPのバージョンアップ時にも役立ったAST 同じソースコードであればASTも同じになる バージョンアップ時に挙動が変わらない根拠としてASTに着目 23 ソースコード AST_STMT_LIST 0: AST_ASSIGN var: AST_VAR
name: "var" expr: "Hello World!" 1: AST_ECHO expr: AST_ENCAPS_LIST 0: AST_VAR name: "var" <?php $var = "Hello World!"; echo "${var}"; 410dfe506da6502f9f81b89710ad379159b644d63520de6eca79f8ed86b6ffc4 1回目 AST ハッシュ値(SHA-256)
PHPのバージョンアップ時にも役立ったAST 同じソースコードであればASTも同じになる バージョンアップ時に挙動が変わらない根拠としてASTに着目 24 ソースコード AST_STMT_LIST 0: AST_ASSIGN var: AST_VAR
name: "var" expr: "Hello World!" 1: AST_ECHO expr: AST_ENCAPS_LIST 0: AST_VAR name: "var" <?php $var = "Hello World!"; echo "${var}"; 410dfe506da6502f9f81b89710ad379159b644d63520de6eca79f8ed86b6ffc4 1回目 AST ハッシュ値(SHA-256) ソースコード AST_STMT_LIST 0: AST_ASSIGN var: AST_VAR name: "var" expr: "Hello World!" 1: AST_ECHO expr: AST_ENCAPS_LIST 0: AST_VAR name: "var" <?php $var = "Hello World!"; echo "${var}"; 2回目 AST
PHPのバージョンアップ時にも役立ったAST “${var}”から”{$var}”に置き換えてもASTが変わらない=挙動も変わらない バージョンアップ時に挙動が変わらない根拠としてASTに着目 25 ソースコード AST_STMT_LIST 0: AST_ASSIGN var: AST_VAR
name: "var" expr: "Hello World!" 1: AST_ECHO expr: AST_ENCAPS_LIST 0: AST_VAR name: "var" <?php $var = "Hello World!"; echo "${var}"; 410dfe506da6502f9f81b89710ad379159b644d63520de6eca79f8ed86b6ffc4 "${var}" AST ハッシュ値(SHA-256) ソースコード AST_STMT_LIST 0: AST_ASSIGN var: AST_VAR name: "var" expr: "Hello World!" 1: AST_ECHO expr: AST_ENCAPS_LIST 0: AST_VAR name: "var" <?php $var = "Hello World!"; echo "{$var}"; "{$var}"; AST
PHPのバージョンアップ時にも役立ったAST ASTのハッシュ値が同じなら変更前後で挙動の変更がないと判断可能 バージョンアップ時に挙動が変わらない根拠としてASTに着目 • “${var}”から”{$var}”に機械的に置き換えてもASTが同じならソース コードの変更前後で挙動の変更もないと見なせる • 技術的に自信を持ってテスト不要と判断できる • ハッシュ値を比較に使うことで差分の有無を簡単に確認できる
26
PHPでASTを取得および そのハッシュ値を比較する方法 27
PHPのバージョンアップ時にも役立ったAST ASTの取得に使ったソフトウェア PHPでASTを取得およびそのハッシュ値を比較する方法 • PHP FoundationのボードメンバーおよびPHPコア開発者の1人である Nikita Popovさんが開発したツールを使用 • php-ast
• https://github.com/nikic/php-ast • PHP-Parser • https://github.com/nikic/PHP-Parser 28 https://github.com/nikic/php-ast?tab=readme-ov-file#differences-to-php-parser
PHPのバージョンアップ時にも役立ったAST php-astでASTを取得するサンプル PHPでASTを取得およびそのハッシュ値を比較する方法 • php-astのutil.phpで定義されているast_dump()を使用してASTを出力 29 https://github.com/nikic/php-ast?tab=readme-ov-file#example
PHPのバージョンアップ時にも役立ったAST ASTを取得およびそのハッシュ値を比較する手順の流れ PHPでASTを取得およびそのハッシュ値を比較する方法 • PHP 8.1の環境にphp-astをインストール • php.iniに「extension=ast.so」(Windowsの場合には 「extension=php_ast.dll」)を追加 •
php-astを使用してASTを出力 • 出力したASTからhash()を使ってハッシュ値(SHA-256)を生成 • 変更前と変更後のハッシュ値を比較して一致するか確認 30
ASTのハッシュ値を確認する際に 留意する点 31
PHPのバージョンアップ時にも役立ったAST 挙動の差が発生する理由や境界を意識する ASTのハッシュ値を確認する際に留意する点 • PHP 8.2からは非推奨を示すエラーメッセージが出力されるように変更さ れていることを考慮すると今回の用途ではPHP 8.1でphp-astを実行する 必要があった •
PHP 8.1でphp-astを使った場合 • ソースコードの変更前後でASTは変わらない • ハッシュ値が一致するか確認する用途に使えた • PHP 8.2でphp-astを使った場合 • ASTおよびASTのハッシュ値が変わる • php-astを使うPhanが影響箇所を検出できたのはこのため • https://github.com/nikic/php-ast/pull/227 32
PHPのバージョンアップ時にも役立ったAST 複数のツールを使ってどの場合に差分が発生するか検証する ASTのハッシュ値を確認する際に留意する点 • PHP-Parserを使った場合にはPHP 8.1でもPHP 8.2でも今回対象としてい る範囲においてはASTは同じだった • 結果として
• 影響箇所を検出するために内部的にphp-astを用いるPhanをPHP 8.2で使った • ASTのハッシュ値が一致するか確認する用途にphp-astをPHP 8.1で使った • 用途や目的に応じて複数のツールを使って検証することはやはり大事 33
PHPのバージョンアップ時にも役立ったAST PHP 8.1でphp-astを使う場合でも一部ハッシュ値が変わるケースが存在 ASTのハッシュ値を確認する際に留意する点 • PHP CS FixerやRectorによる置換ではなく、テキストエディターやIDEを 使って単に「${」を「{$」に一括置換した場合 •
DocComment(/** */で括られるコメント)内にある“${var}”および “${expr}”形式で書かれている文字列を置換した場合はphp-astで取得した ASTのハッシュ値が変わる場合があった • DocComment内を置換しなかった場合にはASTのハッシュ値は同じだった • 最終的にDocComment内部での置き換えであれば挙動への影響はないと判断 34
PHPのバージョンアップ時にも役立ったAST PHP 8.1でphp-astを使う場合でも一部ハッシュ値が変わるケースが存在 ASTのハッシュ値を確認する際に留意する点 35 ソースコード <?php declare(strict_types = 1);
class HelloWorld { /** * "${var}" */ public function sayHello(): string { return "Hello World!"; } } 32e80262eee2882016b752815393917a2d79efda6cdfefb8f8a40e26d7122a75 "${var}" ハッシュ値 ソースコード <?php declare(strict_types = 1); class HelloWorld { /** * "{$var}" */ public function sayHello(): string { return "Hello World!"; } } f71118033b77fbe03e32eb2f971a463e17b938f2c1ce8b70d68872116331e06c "{$var}" ハッシュ値
まとめ 36
PHPのバージョンアップ時にも役立ったAST まとめ まとめ • 実際のプロダクト開発においてPHP 8.1からPHP 8.2にバージョンアップ する作業の一部を効率化し大幅にテスト工数を削減できた • ソースコードを変更した際にASTのハッシュ値が同じなら、プログラムの
変更前後で差分がないと見なすことができ、技術的に自信を持ってテスト 不要と判断できる • アイデア次第でASTは他の場面でも役立つ可能性がある 37
PHPのバージョンアップ時にも役立ったAST “Connecting the dots” まとめ • 勉強会でASTのハッシュ値が同じであればプログラムの変更前と変更後の 間に差分がないと判断できるという発表を聞いたことがきっかけ • 関心を持ち続けながら勉強会に参加しているとふとしたことがきっかけで
後で役に立つことがある • 機会があればカンファレンスや勉強会に参加してみてはいかがでしょうか 38
©️ Cybozu, Inc. 39