2

I'm a bit confused about a parsing error :

class Foo{
    public function some_function(){}        
}

($foo = new Foo())->some_function();

yields

PHP Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ';'

Here is what php-langspec states about a simple assignment expression:

The type and value of the result is the type and value of the left-hand operand after the store (if any [see below]) has taken place. The result is not an lvalue.

Now as I understand it, the assignment result should be equivalent to the variable except it would not be an lvalue (no assignment possible). So why is there an error?

Am I missing something?

EDIT

php version is 5.5.9

This is not related to chaining methods, this is a parsing error not a runtime error.

Bastien
  • 658
  • 1
  • 9
  • 24

1 Answers1

2

Short answer: These kind of expressions work fine now in PHP 7.x. Yeey!


Long answer: PHP's "hand crafted parser" has severe limitations, especially in PHP < 7.0. Lots of complex expressions that you would expect to work, don't.

But it least it keeps its own weird "symmetry": just as it doesn't work for applying the -> operator to the result of an assignment, it also doesn't work for applying the array indexing operator [...].

For example (trying this on PHP 5.6.23):

>>> ($x = new stdClass())->foo                                
PHP Parse error: Syntax error, unexpected T_OBJECT_OPERATOR on line 1

>>> $x = new stdClass()                                 
=> {#334}           
>>> $x->foo                                             
PHP error:  Undefined property: stdClass::$foo on line 1
>>> // this above is the "correct" error you would expect here


>>> ($x = ['name' => 'J'])['name']                     
PHP Parse error: Syntax error, unexpected '[' on line 1

>>> $x = ['name' => 'J']                
>>> $x['name']           
=> "J"                  

Pure speculation: I imagine that fixing these parser inconsistencies was simple, but PHP's core developers' reasoning for not doing this could sound something like "but fixing this would encourage a really bad coding style, since everyone agrees using the results of assignments is a bad practice, so since there is already so much bad PHP code in the wild, why add a fix that would encourage people to write even more bad code". Thankfully, reason prevailed with PHP 7.0.

History: I some past PHP versions, can't remember exactly which, even code like my_function()['attr1'] or $foo->myMethod()->myField was unparse-able, but it had legitimate uses in good code, so the parser got fixed for this to work.

NeuronQ
  • 7,527
  • 9
  • 42
  • 60
  • Alright so basically, php parser is not even compliant with the language specifications. That certainly does not improve the way I see php. – Bastien Feb 01 '17 at 13:44
  • @Bastien agree. people don't choose to use "php as a language", but choose to use "php as platform", although the language is horrible. All about the "shared nothing, 1 process per request" idea from its creator. You can have a team of bad devs writing buggy code using libs with memory leaks, and still ship a working application that scales easy on tens of servers serving zilliond of users (the magic of "it's a bug here, but it only crashes 0.01 percent of requests so out customers don't care, money keeps flowing" - with nodejs or go, you generally have one bug taking down your entire app) – NeuronQ Feb 01 '17 at 14:00
  • @Bastien but as a developer, what I mentioned above only translate to "worse pay" and "more stress", unless you have an unnatural gift for cleaning up other people's code messes :) – NeuronQ Feb 01 '17 at 14:09