首页 > 新闻动态 >  

新闻动态
NEWS

PHP debug_backtrace的胡思乱想

添加时间:2013-5-9 点击量:

本文示例代码测试景象是Windows下的APMServ(PHP5.2.6)



简述


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


好,来复习一下。



one();


function one() {
two();
}

function two() {
three();
}

function three() {
print_rdebug_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];
ifisset¥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.phppackage.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



可以看到,我成功了。


思虑:这个办法我感觉很是强大,除了相对路径之外,可以按照这个思路引伸出相对包、相对模块之类的抽象特点,对于一些项目来说可以加强模块化的感化。




经管文件调用权限


我商定一个规范:文件名前带下划线的只能被当前目次的文件调用,也就是说这种文件属于当前目次‘私有’,其它目次的文件不容许载入它们。


如许做的目标很明白:为了降落代码耦合性。在项目中,很多时辰一些文件只被用在特定的脚本中。然则经常产生的工作是:一些法度员发明这些脚本有本身须要用到的函数或者类,是以直接载入它来达到本身的目标。如许的做