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

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

http://codepad.org/G1TSK1c6
Parse error: syntax error, unexpected ')', expecting T_PAAMAYIM_NEKUDOTAYIM on line 4

I know that empty() only allows variables to be passed as an argument, but why does it expect a T_PAAMAYIM_NEKUDOTAYIM (i.e. ::) when I give it a constant?

5

5 Answers

4
votes

The next logical thing the parser wants is a :: because foo is not a variable.

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

Is the only thing, that works when empty() is not passed a variable. Your example is evaluated as empty(bar) where the parser assumes bar to be a class name and now expects a static member variable.

3
votes

Saw this one while doing some research, although I know this is a bump I thought I would clarify this better.

empty() is not a function, but a language construct. This means that the underlaying parser code is different from that of parsing arguments sent to regular functions or methods. This may seem inconsistent at first when you experience serve error messages like that one, however lets break it down a little.

empty() is expecting to check something thats variable; a constant is not variable so that is not included in the list of possible syntaxes that can be passed to this construct, which makes perfect sense as you would otherwise be doing something illogical (checking for emptiness in a constant value).

The only other possible variables we have in PHP is good old variables and class properties as they are interchangeable, the relevant syntaxes can be represented like this:

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

This means that if you are passing a constant, PHP will read this as the class name and therefore is expecting the double colon token '::', hence why the error makes perfect sense.

Hope this was somewhat insightful ;-)

3
votes

I looked into this, tried it on my local PHP installation and guess what? It worked without a hitch (PHP 5.5.6). After trying the same code on different versions of PHP, I found that it does not work on all versions of PHP < 5.5.x and works otherwise.

So then I took to PHP's documentation, more specifically its changelog from 5.4.x to 5.5.x, and found this:

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

empty() supports arbitrary expressions

Passing an arbitrary expression instead of a variable to empty() is now supported. For example:

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

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

The above example will output:

This will be printed.

So if you're running PHP >= 5.5.x, then this will not be a problem.

You can test the code on different versions of PHP using this service: http://sandbox.onlinephpfunctions.com/. I could not, for the life of me, figure out how to save code samples (I always failed the captcha, even though it's dead simple - I think something MAY be broken on their end).

2
votes

empty() expects variables and not constants. You should use defined() for constants.

1
votes

Just a though, but I think this error is thrown when parsing the code.

foo, is not a variable, nor a string, therefore, in the context of parsing, the next solution may be class attribute., but it is not because there is no ::, but it should be because constants should not be used here, and it remains to be a class attribute or method.