アシアルの中の人
xdebugの実装を調べてみたら、PHPの裏側の仕組みと連携していた
xdebugとは?
拡張ライブラリ
デバッグや開発を支援してくれる
どんな仕組み?
のソースコードを取得してみたら?
コードカバレッジ取得
用途 テストの網羅率を調べる
xdebug_start_code_coverage();で簡単に調べられるよ。
<?php xdebug_start_code_coverage(); function fuga() { echo "fuga"; } echo 'fuga'; fuga(); var_dump(xdebug_get_code_coverage());
実行された行を表示してる。
fugafugaarray(1) {
["/hogehoge.php"]=>
array(6) {
[4]=>
int(1)
[5]=>
int(1)
[6]=>
int(1)
[8]=>
int(1)
[9]=>
int(1)
[11]=>
int(1)
}
}
どういう仕組みで動いているのか?
裏側ではどうやって動作しているのか
- 字句解析(コードをトークの列に格納)
- 構文解析(トークン列から構文を解析)
- コンパイル(ZendEngine用のコードにコンパイル)
- 実行(zend_op_array構造体を解釈してそれを実行、関数、メソッドやファイル読み込みのたびに呼ばれる)
ファイル、関数、メソッド ヒトツニツキzend_op_array構造体に格納
ZendEngine用のコンパイルされたコード
zend_op構造体の列が入っている
zend_op構造体
zendEngineへの命令を表現
命令の種類は多数
PHPでは…
コードをzend_op_array構造体に変換、zend_execute関数に渡して実行
初期化部分で、色々初期化する
zend_set_user_opcode_handler ZendEngineの振舞いを変えるAPI
特定のzend_op命令を解釈して実行する
zend_op実行時の現在の行を記録
実際に実行されたコードの行が分かる
関数トレース
実行した関数をトレースして状態を記録する
xdebug_start_trace( 'C:/Temp/log' ); function hoge($i = 10){ echo $i . PHP_EOL if(0 < $i ) { hoge(--$i); } }
みたいな。
呼び出し時の状態をトレースに保存
その後本来の実行関数を呼び出す
zend_execute ではなく、 xdebug_execute関数を呼び出す
zend_executeをまるまるすげかえて、関数呼び出しをフック
その後本来の実行関数を呼び出して、ログファイルに記録