Yesterday on Twitter there was a conversation started by Marco Pivetta regarding a particularly horrible bit of code he had spotted:
->execute(constant(sprintf('%s::PARAMNAME', get_class($api))));
What the actual f***?
— magic method with side effects (@Ocramius) July 7, 2015
If it’s unclear, this creates a string using sprintf()
by prefixing ::PARAMNAME
with the result of calling get_class()
on the $api
variable, and then passes that string into constant()
which will give you the value of a constant using it’s string name.
At which point Elizabeth Smith chimed in to point out that $api::PARAMNAME
would not work in older versions of PHP, necessitating this horrible workaround.
@Ocramius $api::PARAMNAME didn't used to work in PHP so they're doing great evil weird workaround
— auroraeosrose (@auroraeosrose) July 7, 2015
I then added this to the conversation:
https://twitter.com/dshafik/status/618492223966052354
Turns out, I was wrong. Whoops. Trevor Suarez created a past on 3v4l.org showing that this did indeed work, going back to PHP 5.3 even.
@dshafik @auroraeosrose @ocramius yes it does:http://t.co/OWbn6ON1gB
— Trevor Suarez (@trevorsuarez) July 7, 2015
Additionally, with PHP 7 — thanks to Uniform Variable Syntax — there are many more ways to achieve this too, as you can see below:
https://gist.github.com/dshafik/42e934ead6efca49cc20
Now, obviously, a lot of these are facetious, I mean, who is going to do ['Foo'][0]::BAR
, really? But it’s interesting to see just how consistent, and flexible the new Uniform Variable Syntax is.
The someFunction()::CONSTANT
, SomeClass::method()::CONSTANT
, and $obj->method()::CONSTANT
are much more realistic, and likely to be something you will use at some point.
There were a few syntaxes that didn’t work, which on the one hand, I’m grateful for, but on the other, I think at least some of them should be possible. Presented without further comment:
https://gist.github.com/dshafik/c95439d7d2f4edb9eca6
As with everything in any programming language however:
just because you can do something, doesn’t mean you should
Use with caution.