PHP可以剖析自己的语法吗?

Nat*_*ong 4 php

PHP可以剖析自己的语法吗?例如,我想写一个函数,它接受一个输入,$object->attribute并对自己说:

好吧,他正在给我$foo->bar,这意味着他必须认为这$foo是一个有一个叫做属性的对象bar.在我尝试访问bar并可能获得"尝试获取非对象属性"错误之前,让我检查一下是否$foo是一个对象.

最终目标是在设置值时回显值,如果没有则静默失败.

我想避免像这样重复:

<input value="<? if(is_object($foo) && is_set($foo->bar)){ echo $foo->bar; }?> "/>
Run Code Online (Sandbox Code Playgroud)

...并避免编写执行上述操作的函数,但必须单独传入对象和属性,如下所示:

<input value="<? echoAttribute($foo,'bar') ?>" />
Run Code Online (Sandbox Code Playgroud)

... 而是写一些东西:

  • 保留object-> attribute语法
  • 很灵活:还可以处理数组键或常规变量

像这样:

<input value="<? echoIfSet($foo->bar); ?> />
<input value="<? echoIfSet($baz['buzz']); ?> />
<input value="<? echoIfSet($moo); ?> />
Run Code Online (Sandbox Code Playgroud)

但这一切都取决于PHP能够告诉我"当我说$object->attribute$array[$key]" 时我要求的是什么样的东西,以便我的功能可以根据自己的类型处理每个.

这可能吗?

更新

我在这里得到了一些好的答案并做了一些实验.想总结一下.

  • 我原来的问题的答案似乎是"不",但我们确实找到了一种方法可以实现我想要做的事情.Techpriester指出我可以将字符串'$ foo-> bar'传递给一个函数并让它解析eval()它.不是我想采取的方法,但值得一提.
  • Peter Bailey指出,$foo->bar在传递给函数之前会对它进行评估.我应该想到这一点,但由于某种原因没有.谢谢,彼得!
  • Will Vousden表明,通过$foo->$bar引用传递允许函数对其进行评估,而不是事先对其进行评估.他的功能表明isset($foo->bar)如果$foo不是一个我不知道的对象就不会抱怨.

更有趣的是,他的例子似乎暗示PHP等待评估变量,直到它绝对必须.

如果你按价值传递某些东西,那么PHP当然必须确定价值.像这样:

$foo->bar = 'hi';
somefunction($foo->bar); // same as somefunction('hi');
Run Code Online (Sandbox Code Playgroud)

但是,如果您通过引用传递,它可以等待确定实际需要的值.

像这样(遵循事情发生的顺序):

echo ifSet($foo->bar); // PHP has not yet evaluated $foo->bar...
function ifSet(&$somevar){ // ...because we're passing by reference (&$somevar)
  // Now we're inside the function, but it still hasn't evaluated $foo->bar; it 
  // just made its local variable, $somevar, point to the same thing as $foo->bar
  if(isset($somevar)){ // Right HERE is where it's evaluated - when we need it
    return $bar;
  }
}
Run Code Online (Sandbox Code Playgroud)

感谢大家的回应!如果我有错误的话,请告诉我.

Wil*_*den 6

您可以通过引用传递它:

<?php

function foo(&$bar)
{
    if (isset($bar))
    {
        echo "$bar\r\n";
    }
    else
    {
        echo "It's not set!\r\n";
    }
}

$baz = new stdClass;
$baz->test = 'test';
foo($baz->test);
foo($baz->test2);

$baz = array();
foo($baz['test3']);

?>
Run Code Online (Sandbox Code Playgroud)

请注意,如果您尝试将对象作为数组访问,则此方法无效,反之亦然.

不过,你不应该试图过多依赖这样的东西.