PHP debug_backtrace的胡思乱想
添加时间:2013-5-9 点击量:
本文示例代码测试景象是Windows下的APMServ(PHP5.2.6)
简述
可能大师都知道,php中有一个函数叫debug_backtrace,它可以回溯跟踪函数的调用信息,可以说是一个调试利器。
好,来复习一下。
one();
function one() {
two();
}
function two() {
three();
}
function three() {
print_r( debug_backtrace() );
}
/
输出:
Array
(
[0] => Array
(
[file] => D:\apmserv\www\htdocs\test\debug\index.php
[line] => 10
[function] => three
[args] => Array
(
)
)
[1] => Array
(
[file] => D:\apmserv\www\htdocs\test\debug\index.php
[line] => 6
[function] => two
[args] => Array
(
)
)
[2] => Array
(
[file] => D:\apmserv\www\htdocs\test\debug\index.php
[line] => 3
[function] => one
[args] => Array
(
)
)
)
/
趁便提一下类似的函数:debug_print_backtrace,与之不合的是它会直接打印回溯信息。
回来看debug_backtrace,从名字来看用处很明白,是让开辟者用来调试的。直到有一天我重视到它返回的file参数,file默示函数或者办法的调用脚底本源(在哪个脚本文件应用的)。忽然我想到,若是当前脚本知道调用起原,那是否可以按照这个起原的不合,来实现一些有趣的功能,比如文件权限经管、动态加载等。
实战
实现魔术函数
获取当前函数或办法的名称
尽管PHP中已经有了__FUNCTION__和__METHOD__魔术常量,但我还是想介绍一下用debug_backtrace获取当前函数或者办法名称的办法。
代码如下:
//函数外部输出getFuncName的值
echo getFuncName();
printFuncName();
Object::printMethodName();
//调用了上方两个函数后,再次在外部输出getFuncName,看看是否有‘缓存’之类的题目
echo getFuncName();
function printFuncName() {
echo getFuncName();
}
class Object {
static function printMethodName() {
echo getFuncName();
}
}
/
获取当前函数或者办法的名称
函数名叫getFuncName,好吧,其实method也可以当做function,其实想不出好名字
@return string name
/
function getFuncName() {
¥debug_backtrace = debug_backtrace();
//若是函数名是以下几个,默示载入了脚本,并在函数外部调用了getFuncName
//这种景象应当返回空
¥ignore = array(
include,
include_once,
require,
require_once
);
//第一个backtrace就是当前函数getFuncName,再上一个(第二个)backtrace就是调用getFuncName的函数了
¥handle_func = ¥debug_backtrace[1];
if( isset( ¥handle_func[function] ) && !in_array( ¥handle_func[function], ¥ignore ) ) {
return ¥handle_func[function];
}
return null;
}
//输出:
//null
//printFuncName
//printMethodName
//null
看上去没有题目,很好。
加载相对路径文件
若是在项目中要加载相对路径的文件,必须应用include或者require之类的原生办法,但如今有了debug_backtrace,我可以应用自定义函数去加载相对路径文件。
新建一个项目,目次布局如下:

我想在index.php中调用自定义函数,并应用相对路径去载入package/package.php,并且在package.php中应用同样的办法载入_inc_func.php
三个文件的代码如下(留心index.php和package.php调用import函数的代码):
index.php:
<?php
import( ./package/package.php );
/
加载当前项面前目今的文件
@param string ¥path 相对文件路径
/
function import( ¥path ) {
//获得backstrace列表
¥debug_backtrace = debug_backtrace();
//第一个backstrace就是调用import的起原脚本
¥source = ¥debug_backtrace[0];
//获得调用源的目次路径,和文件路径连络,就可以算出完全路径
¥source_dir = dirname( ¥source[file] );
require realpath( ¥source_dir . / . ¥path );
}
?>
package.php:
<?php
echo package;
import( ./_inc_func.php );
?>
_inc_func.php:
<?php
echo _inc_func;
?>
运行index.php:
//输出:
//package
//_inc_func
可以看到,我成功了。
思虑:这个办法我感觉很是强大,除了相对路径之外,可以按照这个思路引伸出相对包、相对模块之类的抽象特点,对于一些项目来说可以加强模块化的感化。
经管文件调用权限
我商定一个规范:文件名前带下划线的只能被当前目次的文件调用,也就是说这种文件属于当前目次‘私有’,其它目次的文件不容许载入它们。
如许做的目标很明白:为了降落代码耦合性。在项目中,很多时辰一些文件只被用在特定的脚本中。然则经常产生的工作是:一些法度员发明这些脚本有本身须要用到的函数或者类,是以直接载入它来达到本身的目标。如许的做