ソムリエでエンジニアのブログ

ワインの事も書きたいけど基本エンジニア用

PHPでバックトレースを実施する

経緯

Zend frameworkを使ったシステムでGETリクエストに対して想定しない404画面が描写された。
対象のコントローラーには404になる処理は実装されておらず、ログをチェックするもリクエストに対応するコントローラー内を通っていない。
各コントローラーの継承元にログを差し込むと出力される....
どこから継承元が呼び出されているかを確認する為、バックトレース用のメソッドdebug_backtraceを使用し、仕様など調べたので備忘録として残しておく。

debug_backtraceとは...

PHPでバックトレースを生成する為の関数。関数がどこから呼び出されているかを把握する事ができる為、今回のような呼び出し元を調査してエラー原因を特定する時に重宝する。

使い方とサンプルコード

継承元コントローラー

<?php
class AbstractController {
    public function __construct() {
        var_dump(debug_backtrace());
        echo "AbstractController\n";
    }
}
?>

各コントローラー

<?php
require('./Abstract.php');

class SampleB extends AbstractController {
    public function __construct() {
        parent::__construct();
    }
    
    public function getClassName()
    {
        echo 'SampleB';
    }
}
?>
<?php
require('./Abstract.php');

class SampleB extends AbstractController {
    public function __construct() {
        parent::__construct();
    }
    
    public function getClassName()
    {
        echo 'SampleB';
    }
}
?>

呼び出しファイル

<?php
require('./SampleA.php');
$class = new SampleA();
$class->getClassName();
?>

出力

array(2) {
  [0]=>
  array(7) {
    ["file"]=>
    string(22) "/workspace/SampleA.php"
    ["line"]=>
    int(6)
    ["function"]=>
    string(11) "__construct"
    ["class"]=>
    string(18) "AbstractController"
    ["object"]=>
    object(SampleA)#1 (0) {
    }
    ["type"]=>
    string(2) "->"
    ["args"]=>
    array(0) {
    }
  }
  [1]=>
  array(7) {
    ["file"]=>
    string(19) "/workspace/Main.php"
    ["line"]=>
    int(3)
    ["function"]=>
    string(11) "__construct"
    ["class"]=>
    string(7) "SampleA"
    ["object"]=>
    object(SampleA)#1 (0) {
    }
    ["type"]=>
    string(2) "->"
    ["args"]=>
    array(0) {
    }
  }
}
AbstractController
SampleA

出力を確認すると、SampleA.php内で継承元のコンストラクタ処理が呼び出されている事を確認できる。
debug_backtraceを使用する事で、今回のエラーはルーティング競合で別のコントローラーが呼び出されている事が原因であることを特定する事ができた。
※メソッドにパラメータを持たせる事で出力内容を最適化できるので参考リンクを確認してください。

参考

www.php.net