假设我有这样的PHP代码:
$FooBar = "a string";
然后我需要一个这样的函数:
print_var_name($FooBar);
打印:
FooBar
有什么想法如何实现这一点?这在PHP中可能吗?
假设我有这样的PHP代码:
$FooBar = "a string";
然后我需要一个这样的函数:
print_var_name($FooBar);
打印:
FooBar
有什么想法如何实现这一点?这在PHP中可能吗?
当前回答
出于调试的原因,我做了一个检查函数。它就像print_r()的类固醇,很像Krumo,但对对象更有效一点。我想添加var名称检测,灵感来自于Nick Presta的帖子。它检测作为参数传递的任何表达式,而不仅仅是变量名。
这只是检测传递表达式的包装器函数。 大多数案子都没问题。 如果在同一行代码中多次调用该函数,则它将不起作用。
这很好: 死(检查($ this - > getUser()——> hasCredential(“删除”)));
Inspect()是检测传递表达式的函数。
我们得到:$this->getUser()->hasCredential("delete")
function inspect($label, $value = "__undefin_e_d__")
{
if($value == "__undefin_e_d__") {
/* The first argument is not the label but the
variable to inspect itself, so we need a label.
Let's try to find out it's name by peeking at
the source code.
*/
/* The reason for using an exotic string like
"__undefin_e_d__" instead of NULL here is that
inspected variables can also be NULL and I want
to inspect them anyway.
*/
$value = $label;
$bt = debug_backtrace();
$src = file($bt[0]["file"]);
$line = $src[ $bt[0]['line'] - 1 ];
// let's match the function call and the last closing bracket
preg_match( "#inspect\((.+)\)#", $line, $match );
/* let's count brackets to see how many of them actually belongs
to the var name
Eg: die(inspect($this->getUser()->hasCredential("delete")));
We want: $this->getUser()->hasCredential("delete")
*/
$max = strlen($match[1]);
$varname = "";
$c = 0;
for($i = 0; $i < $max; $i++){
if( $match[1]{$i} == "(" ) $c++;
elseif( $match[1]{$i} == ")" ) $c--;
if($c < 0) break;
$varname .= $match[1]{$i};
}
$label = $varname;
}
// $label now holds the name of the passed variable ($ included)
// Eg: inspect($hello)
// => $label = "$hello"
// or the whole expression evaluated
// Eg: inspect($this->getUser()->hasCredential("delete"))
// => $label = "$this->getUser()->hasCredential(\"delete\")"
// now the actual function call to the inspector method,
// passing the var name as the label:
// return dInspect::dump($label, $val);
// UPDATE: I commented this line because people got confused about
// the dInspect class, wich has nothing to do with the issue here.
echo("The label is: ".$label);
echo("The value is: ".$value);
}
下面是inspector函数(和我的dInspect类)的一个例子:
http://inspect.ip1.cc
该页面的文本是西班牙语,但代码简洁,非常容易理解。
其他回答
我真的看不出用例……如果你将输入print_var_name($foobar)什么那么难(和不同)输入打印(“foobar”)代替?
因为即使你要在函数中使用这个,你也会得到变量的本地名称…
无论如何,这是反射手册,以防你需要什么。
您可以使用get_defined_vars()来查找与您试图查找的变量名称具有相同值的变量的名称。显然这并不总是有效,因为不同的变量通常有相同的值,但这是我能想到的唯一方法。
编辑:get_defined_vars()似乎没有正确工作,它返回'var',因为$var在函数本身中使用。$GLOBALS似乎可以,所以我把它改成了这个。
function print_var_name($var) {
foreach($GLOBALS as $var_name => $value) {
if ($value === $var) {
return $var_name;
}
}
return false;
}
编辑:需要明确的是,在PHP中没有好的方法来做到这一点,这可能是因为您不应该这样做。也许有更好的方法来做你想做的事情。
我就是这么做的
function getVar(&$var) {
$tmp = $var; // store the variable value
$var = '_$_%&33xc$%^*7_r4'; // give the variable a new unique value
$name = array_search($var, $GLOBALS); // search $GLOBALS for that unique value and return the key(variable)
$var = $tmp; // restore the variable old value
return $name;
}
使用
$city = "San Francisco";
echo getVar($city); // city
注意:一些PHP 7版本将不能正常工作,因为array_search与$GLOBALS的错误,但所有其他版本都可以正常工作。
请看这个https://3v4l.org/UMW7V
其他用途:
耸耸肩
function varsToArrayAssoc(...$arguments){
$bt = debug_backtrace();
$file = file($bt[0]['file']);
$src = $file[$bt[0]['line']-1];
$pat = '#(.*)'.__FUNCTION__.' *?\( *?(.*) *?\)(.*)#i';
$vars =explode(',',substr_replace(trim(preg_replace($pat, '$2', $src)) ,"", -1));
$result=[];
foreach(func_get_args() as $key=>$v){
$index=trim(explode('$',$vars[$key])[1]);
$result[$index]=$v;
}
return $result;
}
$a=12;
$b=13;
$c=123;
$d='aa';
var_dump(varsToArrayAssoc($a,$b,$c,$d));
它可能被认为是快速和肮脏的,但我个人倾向于使用这样的函数/方法:
public function getVarName($var) {
$tmp = array($var => '');
$keys = array_keys($tmp);
return trim($keys[0]);
}
基本上,它只是创建一个包含一个空/空元素的关联数组,使用需要名称的变量作为键。
然后使用array_keys获取该键的值并返回。
显然,这很快就会变得混乱,在生产环境中不可取,但它可以解决所提出的问题。