Skip to content

Instantly share code, notes, and snippets.

@sasezaki
Last active July 30, 2023 13:51
Show Gist options
  • Save sasezaki/7583773 to your computer and use it in GitHub Desktop.
Save sasezaki/7583773 to your computer and use it in GitHub Desktop.
phpdbg - 新しいオールドスクールデバッガ

phpdbg - 新しいオールドスクールデバッガ

phpdbgcom.png

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コマンドを使う。

terminal.png

上の例で$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コマンドで随時確認できるのでそちらを確認いただきたい。

initファイル

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()));});
:>

WEBアプリケーションでのデバッグ

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!

参考:

@d3y4n
Copy link

d3y4n commented Nov 22, 2013

Thanks! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment