当给出非变量时,为什么空期望T_PAAMAYIM_NEKUDOTAYIM?

时间:2011-03-01 15:47:48

标签: php variables constants

<?php
define('foo', 'bar');

if (empty(foo)) {
  echo 'qux';
}
  

http://codepad.org/G1TSK1c6
  解析错误:语法错误,意外')',在第4行期待T_PAAMAYIM_NEKUDOTAYIM

我知道empty()只允许变量作为参数传递,但是当我给它一个常量时,为什么它期望T_PAAMAYIM_NEKUDOTAYIM(即::)?

5 个答案:

答案 0 :(得分:4)

解析器想要的下一个逻辑事物是::,因为foo不是变量。

if (empty(foo::$bar)) {
}

唯一可以在empty()未传递变量时起作用的东西。您的示例被评估为empty(bar),其中解析器假定bar为类名,现在需要一个静态成员变量。

答案 1 :(得分:3)

在做一些研究时看到这个,虽然我知道这是一个颠簸,我想我会更好地澄清这一点。

empty()不是一个函数,而是一个语言结构。这意味着底层解析器代码与解析发送到常规函数或方法的参数的代码不同。当您遇到像这样的服务错误消息时,这可能看起来不一致,但是让我们分解一下。

empty()期待检查变量的内容;一个常量不是变量,所以它不包含在可以传递给这个结构的可能语法列表中,这非常有意义,因为否则你会做一些不合逻辑的事情(检查常量值中的空虚)。

我们在PHP中唯一可能的变量是好的旧变量和类属性,因为它们是可互换的,相关的语法可以这样表示:

<name>     ::= [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*
<variable> ::= $ <name>
<property> ::= <name> :: <name> || $ <name> :: <name> || $ <name> -\> <name>

这意味着如果你传递一个常量,PHP会将其读作类名,因此期望双冒号标记“::”,因此错误很有意义。

希望这有点有见地; - )

答案 2 :(得分:3)

我调查了这个,在我当地的PHP安装上试了一下,猜猜是什么?它顺利运行(PHP 5.5.6)。在不同版本的PHP上尝试相同的代码后,我发现它不适用于所有版本的PHP&lt; 5.5.x并以其他方式工作。

然后我接受了PHP的文档,更具体地说是从5.4.x到5.5.x的更新日志,并发现了这个:

http://www.php.net/manual/en/migration55.new-features.php#migration55.new-features.empty

  

empty()支持任意表达式

     

现在支持将任意表达式而不是变量传递给empty()。例如:

if (empty(TRUE)) {
    echo "This will NOT be printed.\n";
}

if (empty(FALSE)) {
    echo "This will be printed.\n";
}
  

以上示例将输出:

     

将打印出来。

因此,如果你正在运行PHP&gt; = 5.5.x,那么这不会有问题。

您可以使用此服务在不同版本的PHP上测试代码:http://sandbox.onlinephpfunctions.com/。我不能,为了我的生活,弄清楚如何保存代码示例(我总是失败验证码,即使它很简单 - 我认为 MAY 会在它们的末尾被打破)。

答案 3 :(得分:2)

empty()期望变量而不是常量。您应该使用defined()作为常量。

答案 4 :(得分:1)

只是一个但是我认为在解析代码时会抛出此错误。

foo,不是变量,也不是字符串,因此,在解析的上下文中,下一个解决方案可能是类属性。但它不是因为没有::,而是它应该是因为常量不应该在这里使用,它仍然是一个类属性或方法。