Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PHPのバージョンアップ時にも役立ったAST

 PHPのバージョンアップ時にも役立ったAST

2025-02-22 PHPカンファレンス名古屋2025 レギュラートーク資料
https://fortee.jp/phpcon-nagoya-2025

Atsushi Matsuo

February 22, 2025
Tweet

More Decks by Atsushi Matsuo

Other Decks in Programming

Transcript

  1. PHPのバージョンアップ時にも役立ったAST トークの概要 はじめに • 勉強会で学んだことが実際の業務に役立った事例を紹介 • AST(抽象構文木、Abstract Syntax Treeの略)がPHP 8.1からPHP

    8.2に バージョンアップした際の作業の一部で役立った事例 • ASTのハッシュ値に差分がないことを確認することで大幅にテスト工数を削減 2
  2. 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
  3. 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
  4. 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
  5. 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)
  6. 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
  7. 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
  8. 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
  9. 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
  10. PHPのバージョンアップ時にも役立ったAST PHP 8.1でphp-astを使う場合でも一部ハッシュ値が変わるケースが存在 ASTのハッシュ値を確認する際に留意する点 • PHP CS FixerやRectorによる置換ではなく、テキストエディターやIDEを 使って単に「${」を「{$」に一括置換した場合 •

    DocComment(/** */で括られるコメント)内にある“${var}”および “${expr}”形式で書かれている文字列を置換した場合はphp-astで取得した ASTのハッシュ値が変わる場合があった • DocComment内を置換しなかった場合にはASTのハッシュ値は同じだった • 最終的にDocComment内部での置き換えであれば挙動への影響はないと判断 34
  11. 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}" ハッシュ値