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

Posted

技术标签:

【中文标题】当给出非变量时,为啥空期望 T_PAAMAYIM_NEKUDOTAYIM ?【英文标题】:Why does empty expect T_PAAMAYIM_NEKUDOTAYIM when a non-variable is given?当给出非变量时,为什么空期望 T_PAAMAYIM_NEKUDOTAYIM ? 【发布时间】:2011-07-06 14:53:11 【问题描述】:
<?php
define('foo', 'bar');

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

http://codepad.org/G1TSK1c6 解析错误:语法错误,意外的 ')',预计第 4 行有 T_PAAMAYIM_NEKUDOTAYIM

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

【问题讨论】:

【参考方案1】:

解析器想要的下一个合乎逻辑的东西是::,因为foo 不是变量。

if (empty(foo::$bar)) 

只有当empty() 没有传递变量时有效。您的示例被评估为 empty(bar),其中解析器假定 bar 是一个类名,现在需要一个静态成员变量。

【讨论】:

+1,虽然它更像foo::bar(),因为变量不包含在命名空间中。 @casablanca 不是命名空间。在这里,它是对静态成员变量的访问。【参考方案2】:

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

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 会将其读取为类名,因此期待双冒号标记“::”,因此该错误是完全合理的。

希望这有点洞察力;-)

【讨论】:

【参考方案3】:

我对此进行了研究,并在我的本地 PHP 安装上进行了尝试,你猜怎么着?它工作顺利(PHP 5.5.6)。在不同版本的 PHP 上尝试了相同的代码后,我发现它不适用于所有版本的 PHP

然后我查看了 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 >= 5.5.x,那么这将不是问题。

您可以使用此服务在不同版本的 PHP 上测试代码:http://sandbox.onlinephpfunctions.com/。在我的一生中,我无法弄清楚如何保存代码示例(我总是无法通过验证码,即使它非常简单 - 我认为某些东西可能被破坏了)。 p>

【讨论】:

【参考方案4】:

empty() 需要变量而不是常量。你应该使用defined() 作为常量。

【讨论】:

是的,PHP 的输出也这么说,这就是我问这个的原因。 阐明了原因,即 empty 期望变量而不是常量。您可以将defined() 用于常量。 我已经在我的问题中注意到了这一点。我只是想知道为什么 PHP 需要一个 paamayim nekudotayim。【参考方案5】:

虽然只是,但我认为在解析代码时会引发此错误。

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

【讨论】:

以上是关于当给出非变量时,为啥空期望 T_PAAMAYIM_NEKUDOTAYIM ?的主要内容,如果未能解决你的问题,请参考以下文章

method="GET" 给出空 $_GET,method="POST" 给出非空 $_GET。为啥? (PHP 5.6.6)

为啥变量变为空?

为啥非空列表会抛出空指针异常?

当期望输出 10,000 个数字时,为啥 python 只输出 6 个由 '...' 分隔的数字? [复制]

为啥这个涉及 floor 函数的公式没有给出我期望的结果?

为啥 C# 6.0 在使用 Null 传播运算符时不允许设置非 null 可空结构的属性?