我有一个功能
function my_dump($a,$name){
echo '<pre>'.$name.":\n";
var_export($a);
echo '</pre>';
}
如何仅使用一个参数来实现这一点,以便函数识别被调用变量本身的名称?
例如:
my_dump($cool_variable_name);
将输出:
名称:“cool_variable_name”
内容:数组(...
我有一个功能
function my_dump($a,$name){
echo '<pre>'.$name.":\n";
var_export($a);
echo '</pre>';
}
如何仅使用一个参数来实现这一点,以便函数识别被调用变量本身的名称?
例如:
my_dump($cool_variable_name);
将输出:
名称:“cool_variable_name”
内容:数组(...
如果你需要调试代码,那么使用像 xdebug 这样的工具比自制变量转储更灵活、更高效;但是debug_backtrace()(虽然开销很大)可能会给你你需要的东西。提取对调试转储函数的调用的文件名和行号,并解析该行以提取调用函数时使用的变量名
function my_dump($a) {
$backtrace = debug_backtrace()[0];
$fh = fopen($backtrace['file'], 'r');
$line = 0;
while (++$line <= $backtrace['line']) {
$code = fgets($fh);
}
fclose($fh);
preg_match('/' . __FUNCTION__ . '\s*\((.*)\)\s*;/u', $code, $name);
echo '<pre>'.trim($name[1]).":\n";
var_export($a);
echo '</pre>';
}
$foo = 'bar';
$baz = array(
'Hello',
'World'
);
my_dump($foo);
my_dump(
$baz
);
如果您的 PHP 版本不支持数组取消引用,请更改
$backtrace = debug_backtrace()[0];
至
$backtrace = debug_backtrace();
$backtrace = $backtrace[0];
如果您对 my_dump() 的调用跨越多行(例如我的 $baz 示例),您将需要一个稍微复杂的解析器来从代码中提取变量名称。
...请您原谅新答案而不是更改以前的答案,但是阅读时间太长(因此不舒服)。
以下是先前答案中的功能,该功能已针对此功能的多次使用进行了改进。此版本能够在一行中多次使用的情况下获取正确变量的名称。
它不能获得多个变量的名称 - 至少因为我认为它不会很好(对任何事情都有用)。
差异:
正则表达式结果的新处理
参数 $Index 不是必需的 - 但是除了第一次使用该函数之外,它会忽略它会给出错误的结果
表达式中的 \x20 表示空格
try-catch 块中的异常类和异常消息可以根据需要重写
功能的受保护状态可以更改或删除
protected function Get_VariableNameAsText($Variable="", $Index="")
{
$File = file(debug_backtrace()[0]['file']);
try
{
if(!empty($Index) && !is_integer($Index))
{
throw new UniT_Exception(UniT_Exception::UNIT_EXCEPTIONS_MAIN_PARAM, UniT_Exception::UNIT_EXCEPTIONS_PARAM_VALTYPE);
}
}
catch(UniT_Exception $Exception)
{
$Exception -> ExceptionWarning(__CLASS__, __FUNCTION__, $this -> Get_Parameters(__CLASS__, __FUNCTION__)[1], gettype($Index), 'integer');
}
for($Line = 1; $Line < count($File); $Line++)
{
if($Line == debug_backtrace()[0]['line']-1)
{
preg_match_all('/'.__FUNCTION__.'\((?<type>[a-z]{1,}\:{2}\${1}|\$this\x20{0,1}\-\>{1}\x20{0,1}|\${1})(?<variable>[A-Za-z0-9_]{1,})\x20{0,1}\,{0,1}\x20{0,1}(?<index>[0-9]{0,})\x20{0,}\)/', $File[$Line], $VariableName, PREG_SET_ORDER);
if(empty($Index))
{
return $VariableName[0]['type'].$VariableName[0]['variable'];
}
else
{
return $VariableName[$Index]['type'].$VariableName[$Index]['variable'];
}
}
}
}
我希望它会帮助你,喜欢或比以前的版本更好。
编辑:新表达式允许使用更多类型的变量(不仅常见)。
function my_dump($a) {
$backtrace = debug_backtrace()[0];
$fh = fopen($backtrace['file'], 'r');
$line = 0;
while (++$line <= $backtrace['line']) {
$code = fgets($fh);
}
fclose($fh);
preg_match('/' . __FUNCTION__ . '\s*\((.*)\)\s*;/u', $code, $name);
echo '<pre>'.trim($name[1]).":\n";
var_export($a);
echo '</pre>';
}
它运行不正确 - 因为使用的表达式没有给出正确的结果。
使用 \s* 没有意义,因为函数名和带参数的括号之间不能有任何东西。
使用; 在表达上也没有任何意义。至少因为它只允许独立使用这个函数,其中这个函数的结果被赋予 else 变量。但有时可能需要将此函数用作参数。
并且使用 (.*) 也将允许作为参数给出的变量名后面的所有内容 - 即使有分号。
因此,需要从结果中排除结束括号 ) 的符号。有很多方法可以做到这一点。
您可以使用以下函数代码中的表单或此(或其他)
'/'.__FUNCTION__.'\((\w+)\)/'
整个函数可以非常简化为(例如,这是类函数的情况):
protected function Get_VariableNameAsText($Variable="")
{
$File = file(debug_backtrace()[0]['file']);
for($Line = 1; $Line < count($File); $Line++)
{
if($Line == debug_backtrace()[0]['line']-1)
{
preg_match('/'.__FUNCTION__.'\(([^\)]*)\)/', $File[$Line], $VariableName);
return trim($VariableName[1]);
}
}
}
我删除了 var_export 的使用,因为我不明白为什么要使用它,而我只想将变量名作为字符串(文本)获取。在这个函数之外打印给定的字符串更好。
如果你没有 5.4 或更高版本,则需要更改代码
$File = file(debug_backtrace()[0]['file']);
if($Line == debug_backtrace()[0]['line']-1)
上
$Trace = debug_backtrace();
$File = file($Trace[0]['file']);
if($Line == $Trace[0]['line']-1)
如果它是一个简单的脚本,其中所有变量都在全局范围内定义,您可以获得 $GLOBALS 解决方案:
function my_dump($a){
if(is_string($a) and isset($GLOBALS[$a])) {
echo "varname: $a\n";
$a=&$GLOBALS[$a];
}
echo '<pre>'.$name.":\n";
var_export($a);
echo '</pre>';
}
这样您就可以使用变量名调用转储函数
my_dump("cool_variable_name");
代替
my_dump($cool_variable_name);
没有办法做到这一点。
当函数被调用时,参数的值被粘贴到你的 $a 中,所以每次尝试获取它的名称都会返回“a”。
http://us3.php.net/get_defined_vars将失败,因为它只返回函数内部的变量(这意味着“a”)。
您可以将数组与一个项目一起使用,但我想这不是您打算做的。