Foo Bar
Foo Bar

Reputation: 1892

Is using the short notation for directly called function safe in PHP7?

Since PHP7 it seems to be possible to directly call anonymous functions like this:

(function () { echo 'Hello!'; })();

I found this by accident in some open source code base. I tried to find any hint on this in the PHP documentation (including changelogs and RFCs). There seems to be none, it seems fully undocumented.

Is it safe to call functions this way or should I use call_user_func(); like in the old days? Is this documented somewhere?

I know of these questions and answers:

They just say it's supposed to work and how it works. I know this. My question is not about the "how"! It's about whether this is actually an official PHP feature or if it'S merely working "by accident" (because it seems undocumented).

Upvotes: 0

Views: 138

Answers (2)

IMSoP
IMSoP

Reputation: 97688

The reason you won't find this documented as a feature in the main manual is because it isn't one, it's just a consequence of other features:

  • function () { echo 'Hello!'; } creates a Closure object
  • putting () after a Closure object executes that closure

That's not quite the same as accidental, but I can see why you might think that, because it didn't work in PHP 5.

The reason it changed is that PHP's parser was overhauled in PHP 7.0 to use more consistent rules when parsing variables, as well as introducing an extra stage called an Abstract Syntax Tree. This changed the meaning of some code, but allowed for other cases that logically should have been possible, but were previously hard to implement.

Allowing code that was previously a syntax error is not generally considered a compatibility break, so not every piece of syntax enabled by this change made it into migration guides.

However, removing this functionality - even if not documented - would be a compatibility break, so at the very least you will get some notice that it's going to change, and it would be in a "major version" (9.0, 10.0, etc). Since it's a useful piece of syntax, there's no reason to suppose it will ever stop working, unless there's some even more useful feature that conflicts with it for some reason.

Upvotes: 6

Nico Haase
Nico Haase

Reputation: 12104

Just to put some thoughts together: (function () { echo 'Hello!'; }) defines a class instance of type Closure. Putting the closure into a variable helps to understand that:

$x = (function () { echo 'Hello!'; });
echo gettype($x);

This prints object, since PHP 5.3. The result of $x(); hasn't changed since PHP 5.3 either. But what has changed is the unified handling of variables - this enables that you don't have to define a variable explicitly, but call the closure directly as if you had put it in a variable first

Upvotes: 1

Related Questions