PHPのコア周辺での活動が顕著な krakjoe -Joe Watkins
氏に
より新しいプロジェクトが発足した。PHP用デバッガ phpdbg だ。ここ数日karkjoe・felipensp両氏により活発に開発が行われている。
これは、C言語開発者にはお馴染みのGDBに似たデバッグ環境をPHP向けに提供する。 特徴的なのは、これがPHP SAPIとして作成されていることだろう。
READMEや公式サイトに記載されているFeaturesを踏まえ特徴をあげる
- ステップ実行デバッグ
- 柔軟なブレイクポイント(クラスメソッド、関数、ファイル:実行行、アドレス)
- 組み込みeval()への簡単なアクセス
- 実行されているコードへの簡単なアクセス
- ユーザランドAPI
- 寛容なSAPI - 統合が容易
- PHP設定ファイルサポート
- スーパーグローバル($_GETなど)をJust In Timeに
- オプションとしてreadlineサポート
簡単な例として以下のようなスクリプトを動かしてみよう。
<?php
class McHammer
{
private $debug = false;
public function sing($song)
{
$song = 'Break Down!'.$song;
echo $song, "\n";
if ($this->debug === true) {
echo "U Can't Touch This!", "\n";
}
}
}
$yourdebugger = 'phpstorm';
(new McHammer)->sing($yourdebugger);
もちろんこれをPHP-CLIで実行したときの結果は以下の通りだ。
Break Down!phpstorm
ではphpdbgで実際にステップ実行ならびに変数の書き換えを行ってみよう。
起動後にexec
コマンドにて実行ファイルを指定できるが、何度も同じスクリプトを実行する場合は-e
オプションが便利だ。実際にrun
をする前やブレイクポイント中での対象中のコードを確認するにはlist
コマンドを使う。
上の例で$yourdebugger変数への代入を行っている18行目へブレイクポイントを挿入し実行してみよう
phpdbg> break 18
[Breakpoint #0 added at /home/sasezaki/tmp/sample.php:18]
phpdbg> run
[Attempting compilation of /home/sasezaki/tmp/sample.php]
[Success]
[Breakpoint #0 at /home/sasezaki/tmp/sample.php:18]
00017:
>00018: $yourdebugger = 'phpstorm';
00019: (new McHammer)->sing($yourdebugger);
ここのブレイクポイントに来た時点では、まだ代入は行われていない。
phpdbg> eval var_dump($yourdebugger);
NULL
続けて、19行目でもブレイクポイントをはさみ、遷移してみよう
phpdbg> break 19
[Breakpoint #1 added at /home/sasezaki/tmp/sample.php:19]
phpdbg> next
[Breakpoint #1 at /home/sasezaki/tmp/sample.php:19]
00018: $yourdebugger = 'phpstorm';
>00019: (new McHammer)->sing($yourdebugger);
00020:
ここで、変数の内容を書き換え処理を再開してみる
phpdbg> eval $yourdebugger = 'PDT';
PDT
phpdbg> finish
Break Down!PDT
最初の特徴に示した通り、ブレイクポイントはメソッド指定なども行える。 次の例では、オブジェクトへのブレイク時にプライベート変数のフラグを書き換えを行っている。
phpdbg> break McHammer::sing
[Breakpoint #0 added at McHammer::sing]
phpdbg> run
[Attempting compilation of /home/sasezaki/tmp/sample.php]
[Success]
[Breakpoint #0 in McHammer::sing() at /home/sasezaki/tmp/sample.php:7]
00006:
>00007: public function sing($song)
00008: {
phpdbg> eval $this
McHammer Object
(
[debug:McHammer:private] =>
)
phpdbg> eval var_dump($this->debug);
bool(false)
phpdbg> eval $this->debug = true;
1
phpdbg> next
Break Down!phpstorm
U Can't Touch This!
各コマンドについては、開発が始まったため追加やブラッシュアップが行われるであろうが、
help
コマンドで随時確認できるのでそちらを確認いただきたい。
PHP CLIと同様にauto_prepend_fileなどは使用できないが、.phpdbginitという形式の初期化ファイルを設定することができる。 phpdbgのリポジトリ中には簡単な例が記載されている。 https://github.com/krakjoe/phpdbg/blob/master/.phpdbginit
phpdbg実行時のreadlineにて組み込み関数の候補をだす場合は、以下のような.phpdbginitを用意し、-i
オプションで起動すればよい。
<:
readline_completion_function(function(){return array_merge(get_defined_functions()['internal'],array_keys(get_defined_constants()));});
:>
PHPのデバッガであるからには、関心としてはWEBアプリケーションの開発での利用法だろう。
ドキュメント http://phpdbg.com/docs/getting-started にはサーバのモックとして、run
前にスーパーグローバルを設定する簡単な例が用意されている。
https://github.com/krakjoe/phpdbg/blob/master/web-bootstrap.php
上記の方法による毎回リクエスト値を設定するやり方は面倒だ。 もちろん、普段サーバに組み込まれるPHPでサーバを組むことは自然なことなので、 下記のindex.phpは、Zend Framework 2 アプリケーション を react-zf2 モジュールを用いて react上で動かす場合のphpdbg用の差し替えサンプルだ。
https://gist.github.com/sasezaki/7582951
run の後にブラウザでアクセスするとブレイクポイントで止まることが確認できるだろう。
[sasezaki@] $ ./phpdbg -e /home/sasezaki/var/www/zf22react/public/index.php [~/php-src/php-5.5.6/sapi/phpdbg]
[Welcome to phpdbg, the interactive PHP debugger, v0.0.2-dev]
To get help using phpdbg type "help" and press enter
[Please report bugs to <http://github.com/krakjoe/phpdbg/issues>]
phpdbg> break Application\Controller\IndexController::indexAction
[Breakpoint #0 added at Application\Controller\IndexController::indexAction]
phpdbg> run
[Attempting compilation of /home/sasezaki/var/www/zf22react/public/index.php]
[Success]
[Breakpoint #0 in Application\Controller\IndexController::indexAction() at /home/sasezaki/var/www/zf22react/module/Application/src/Application/Controller/IndexController.php:27]
00026:
>00027: return new ViewModel();
00028: }
yay!
参考:
Thanks! :)