Slide 1

Slide 1 text

phpinfoの写経します

Slide 2

Slide 2 text

自己紹介 てきめん ● https://tekitoh-memdhoi.info ● @youkidearitai PHPわかりません php-srcへのバグ報告を 1件やったことがあります PHPerKaigi 2020のときのAR写真 (ARCoreで自作したアプリ)

Slide 3

Slide 3 text

とは PHPの設定を知るための関数 https://www.php.net/phpinfo 引数$flagが設定できる。省略するとINFO_ALLで全て出力。 実行するSAPI(Server API)でhtmlかtextにわかれるので、 実行するSAPIでphpinfoを見るべき。 例えば、CLIで実行するバッチなのに、apache2handlerで出力されるphpinfoを見たりすると、設定 値が違ってしまいハマるとかありえる。

Slide 4

Slide 4 text

写経します ● エンジニアは学ぶためにソースコードを写経する ● phpinfoを学びたい 故にphpinfoを写経していこう extensionを作って、そこに書き写していく https://github.com/youkidearitai/study_extension

Slide 5

Slide 5 text

phpinfoはどこにある 書き写す元の、phpinfo関数はどこにあるのかというと ext/standard/info.cにある

Slide 6

Slide 6 text

SAPIによる出力の分け方 sapi_module.phpinfo_as_textが非0ならばテキス トで出力される。出力のたびにこのif-elseが出てくる if (!sapi_module.phpinfo_as_text) { php_print_info_htmlhead(); } else { php_info_print("phpinfo()\n"); } 嫌な予感しかしない

Slide 7

Slide 7 text

書き写していく メイン部分はphp_print_info関数 引数$flagから、出力する部分のビットをチェックして いき、1だったら出力するようになっている if (flag & PHP_INFO_GENERAL) { // configureオプション等一番上のtable } phpinfo(0); は何も出ないということになる

Slide 8

Slide 8 text

オレオレphpinfoができる

Slide 9

Slide 9 text

html版のロゴを表示する部分 the_time = time(NULL); ta = php_localtime_r(&the_time, &tmbuf); php_info_print("tm_mon==3) && (ta->tm_mday==1)) { php_info_print(PHP_EGG_LOGO_DATA_URI "\" alt=\"PHP logo\" />"); } else { php_info_print(PHP_LOGO_DATA_URI "\" alt=\"PHP logo\" />"); } ここはPHPのロゴを表示しているところ。 なぜ時刻を取得して条件分岐してるの? localtime_rというC言語のtime.hの関数を使っている この2つの定数はext/standard/info.hにある

Slide 10

Slide 10 text

🥚イースター・エッグ🥚 実は4月1日限定で、phpinfoのロゴが変わる…! 🥚PHP版イースター・エッグ!🥚 あと数日で4月1日ですね? 📝 確かめてみよう!📝 (html版のみ)

Slide 11

Slide 11 text

PHPerKaigiのトリにふさわしいネタを見つけた!! やった!!

Slide 12

Slide 12 text

おわり? (背景が黒になります)

Slide 13

Slide 13 text

if (!sapi_module.phpinfo_as_text) { php_print_info_htmlhead(); } else { php_info_print("phpinfo()\n"); } C言語読み書きできなくても、出力するごとにif-else書 いてて漏れとかないの?って思いませんか? これを元に次を見てください

Slide 14

Slide 14 text

if ((flag & PHP_INFO_CREDITS) && !sapi_module.phpinfo_as_text) { php_info_print_hr(); php_print_credits(PHP_CREDITS_ALL & ~PHP_CREDITS_FULLPAGE); } INFO_CREDITSの部分です。C言語読み書きできなくて もおかしいと感じませんか? elseがないですよね? textで出力するときどうなる?

Slide 15

Slide 15 text

確認してみましょう。 CLIのとき、クレジットが表示されません。 tekimen:~/src/php-src$ php -v && php -r 'phpinfo(INFO_CREDITS);' PHP 7.4.15 (cli) (built: Feb 24 2021 00:46:46) ( ZTS DEBUG ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies phpinfo() tekimen:~/src/php-src$ これ、いつからこうなっていたと思いますか?

Slide 16

Slide 16 text

PHP 4.3.0からずっとこうだったようです。 phpinfoがCLIに対応してからずっと… - add phpinfo() support for CLI. (GitHubへのリンク)によると、 2002年8月29日からこの挙動だったようです。 PHP 4.3.0のリリースは 2002年12月27日

Slide 17

Slide 17 text

クレジットが表示されない理由が見つからなかったので、 バグ報告しました。 summaryを修正頂きました。→ 英語下手で恥ずかしい phpcreditsという関数があり、そ ちらはCLIで表示できるので、それ を表示するべきだと指摘しました。

Slide 18

Slide 18 text

PHP 7.4とPHP 8.0で修正され、次のリリースで反映され ます。 $ php -i textの phpinfo htmlの phpinfo 表示されない 表示される 表示される $ php -i は、phpinfoを呼び出すオプションです。 しかし、今回の修正で、クレジットは表示されないままとなります。 表にすると以下のようになります。 (PHP 7.4.17、PHP 8.0.4)

Slide 19

Slide 19 text

ひとことで、まとめると 「phpinfoの写経をしたらイースター・エッグをみつけてウキウキしてたら 18年眠っていたバグを見つけてしまいLTに入り切らず困ってしまった!」 4月1日に phpinfo(); 見よう!

Slide 20

Slide 20 text

ご清聴ありがとうございました。 18年5ヶ月20日、日数にすると6748日、 バージョンにするとPHP 4.3.0 – PHP 8.0.xまで眠っていたこのバグを見つけたとき、歴史を掘 り起こしたような気持ちになりました。 今回のバグは、携わってきた方々と、変化の目まぐるしいこの業界の中での18年の長さな ど、PHPの歴史に思いを馳せることのできる、貴重な機会でした。 このレイヤーで 調べ物をすると、昔過ぎて携わった方々も変わっていっていることを実感しま した。背中押してくれた方々に直接お礼言えるのマジで貴重。 ありがとうございました。 ※このポエムはLTに入り切らないので省略予定 tekimen:~/src/php-src$ php -r '$from = new DateTime("2002-08-29"); $to = new DateTime("2021-02-18"); var_dump($from->diff($to)->days);' int(6748) 2002年当時私は15歳です