PHP has come a long way in recent years, and though it’s still not by far the most elegant language ever PHP5.3+ at least looks like an actual programming language.
But today I got bitten by something that totally flabbergasted me. Consider the following code:
<?php
$foo = new Foo;
Obviously, without any autoloading mechanism this gives a fatal error as class Foo
is undefined. Now, modern versions of PHP have a handy feature where you can call ClassName::class
and get the actual classname. This is handy for when it’s imported from some long namespace like so:
<?php
use Foo\Bar\Baz\Fizz\Buzz;
echo Buzz::class; // 'Foo\Bar\Baz\Fizz\Buzz'
So what do you expect happens when you do this to a non-existing class? After all, ::class
is some sort of virtual constant on an actual class definition, right?
Wrong.
<?php
echo Foo::class; // 'Foo'
$foo = new Foo; // fatal error, class does not exist
Ehm… That’s just… Wow.
The only reason I can think of why this works as it does is that the ::class
is evaluated at compile time, while the actual instantiation is triggered at run time (thus causing autoloading to kick in).
To add to the party, I ran into this doing a Laravel project, and the autoloader swallows errors in the autoloaded class and simply says “sorry, no such class” (there was actually a typo in the loaded class, which I’d love to have been notified about before wasting an hour). I still need to find out what exactly is going on there, but I’m pretty sure it’s not Composer – I’ve never run into this behaviour on non-Laravel projects. (Also, the error occured in a Laravel “Command” which eagerly swallows errors too, because fuck you programmers debugging stuff.)
Tl;dr: just complain loudly if stuff fails. It’s fine. If I want to handle live errors more gracefully, I’ll just try/catch index.php
or whatever myself based on some environment variable thank you very much.