简述

可能大家都知道,php中有一个函数叫debug_backtrace,它可以回溯跟踪函数的调用信息,可以说是一个调试利器。

好,来复习一下

01    one();
02     
03    function one() {
04        two();
05    }
06     
07    function two() {
08        three();
09    }
10     
11    function three() {
12        print_r( debug_backtrace() );
13    }
14     
15    /*
16    输出:
17    Array
18    (
19        [0] => Array
20            (
21                [file] => D:\apmserv\www\htdocs\test\debug\index.php
22                [line] => 10
23                [function] => three
24                [args] => Array
25                    (
26                    )
27     
28            )
29     
30        [1] => Array
31            (
32                [file] => D:\apmserv\www\htdocs\test\debug\index.php
33                [line] => 6
34                [function] => two
35                [args] => Array
36                    (
37                    )
38     
39            )
40     
41        [2] => Array
42            (
43                [file] => D:\apmserv\www\htdocs\test\debug\index.php
44                [line] => 3
45                [function] => one
46                [args] => Array
47                    (
48                    )
49     
50            )
51     
52    )
53    */

顺便提一下类似的函数:debug_print_backtrace,与之不同的是它会直接打印回溯信息。

回来看debug_backtrace,从名字来看用途很明确,是让开发者用来调试的。直到有一天我注意到它返回的file参数,file表示函数或者方法的调用脚本来源(在哪个脚本文件使用的)。忽然我想到,如果当前脚本知道调用来源,那是否可以根据这个来源的不同,来实现一些有趣的功能,比如文件权限管理、动态加载等。

 

实战

实现魔术函数 

获取当前函数或方法的名称 

尽管PHP中已经有了__FUNCTION____METHOD__魔术常量,但我还是想介绍一下用debug_backtrace获取当前函数或者方法名称的方法。

代码如下:

01    //函数外部输出getFuncName的值
02    echo getFuncName();
03     
04    printFuncName();
05     
06    Object::printMethodName();
07     
08    //调用了上面两个函数后,再次在外部输出getFuncName,看看是否有‘缓存’之类的问题
09    echo getFuncName();
10     
11     
12     
13    function printFuncName() {
14        echo getFuncName();
15    }
16     
17    class Object {
18        static function printMethodName() {
19            echo getFuncName();
20        }
21    }
22     
23    /**
24     * 获取当前函数或者方法的名称
25     * 函数名叫getFuncName,好吧,其实method也可以当做function,实在想不出好名字
26     *
27     * @return string name
28     */
29    function getFuncName() {
30        $debug_backtrace = debug_backtrace();
31        //如果函数名是以下几个,表示载入了脚本,并在函数外部调用了getFuncName
32        //这种情况应该返回空
33        $ignore = array(
34            'include',
35            'include_once',
36            'require',
37            'require_once'
38        );
39        //第一个backtrace就是当前函数getFuncName,再上一个(第二个)backtrace就是调用getFuncName的函数了
40        $handle_func = $debug_backtrace[1];
41        if( isset( $handle_func['function'] ) && !in_array( $handle_func['function'], $ignore ) ) {
42            return $handle_func['function'];
43        }
44        return null;
45    }
46     
47     
48    //输出:
49    //null
50    //printFuncName
51    //printMethodName
52    //null
View Code

相关文章: