Debugging or Troubleshooting the PHP Autoloader

I used PHP pretty heavily a while ago. It’s still – in its primitive, non-objectey, non-frameworked form – one of the environments in which I can ‘think’ in the language the fastest. If someone had a gun to my head and said “build me this thing ‘x'” – I would probably do it in PHP (unless it were large enough with lots of forms/fields/tables/etc., then I might use something else. Or maybe still PHP? I dunno.)

But that means I missed out on the newest revolutions in PHP – composer, Laravel, all that stuff. And some of it is actually pretty cool, once you get a handle on it.

Composer is very similar to how Bundler works under Ruby, or how npm works under Node. You say which libraries you need and which versions in a config file, then say ‘composer install’ (or ‘php composer.phar install’) and it magically goes and gets them and installs them. Pretty neat.

One of the more subtle pieces you get is no longer having to say require "foo.php"; – the new system of Autoloading does that for you, if you’ve gotten everything set up right. It seems to be powered by PHP Namespaces – each composer-able package declares which namespace it’s going to set stuff up in, and then if you try and use something from that namespace, it automagically gets loaded up. Pretty neat!

It’s actually very neat. Until…it doesn’t work. And then I started to find that it was extremely difficult to troubleshoot what it’s actually doing, and why my custom package wouldn’t autoload.

Probably the first place to start should be the DebugClassLoader component ("/Symfony/Component/Debug/DebugClassLoader.php"). That was installed by default in the Laravel app I was playing with. It looks like there’s a nice static class method you can invoke, which will help troubleshoot what’s going on in the class-loading process – “DebugClassLoader::enable()“. There seemed to be another Debug component – somewhere – that wanted to enable that feature – “/Symfony/Component/Debug/Debug.php” – but I couldn’t end up figuring out how to turn the damned thing on. If you do? I bet that’ll be more helpful than the other stuff I ended up playing around with. That DebugClassLoader seems like it will wrap the autoloading process and yell at you if it can’t find the classes it wants in the appropriate files, and there’s not a lot else going on with the autoload sequence than that.

But, due to my ignorance, the most useful tool that worked for me was manually loading up the autoloader object and just asking it dumb questions:

$autoloader = require "./vendor/autoload.php";

$results = $autoloader->findFile("\MyNamespace\MyClassName");

print "Found file for class at: $results";
exit(1);

Other methods I ended up playing with were:

$autoloader->loadClass("\MyNamespace\MyClassName");

print_r($autoloader);
exit(2);

Enough poking around with some of these techniques eventually got me to the point where I could figure out what it was that I was doing wrong. Hopefully I can save someone else a few hours of heartache too.

In half-hearted defense of PHP

Okay now there’s a big rant about PHP. These things are getting exhausting. I don’t particularly like Python, that doesn’t mean I have to make any kind of long boring post about it. It’s just a matter of my personal preference, and I know that. Plenty of people do plenty of nice things in Python and that’s great. Twisted seems like a cool idea. But I don’t like Python. And no one cares, and no one should care.

So the rant on PHP has a similar tenor to the ones about Node.js – which already starts us off on the wrong foot. However, as I read through the whole thing, I find that I can’t disagree with any one particular point. Every single one seems at least conditionally valid, and at least none of them seem deliberate designed to be maliciously false. So, points to you sir and/or m’am on your post. My rebuttal follows.

I’ve been using PHP for somewhere around 10 or 15 years or so, and I haven’t run into even half of those various weird edge-cases. I’m not saying they don’t exist. They seem like they do. But I’m saying you don’t run into them so often.

However, I do feel that the long, exhaustive list of ‘things that are wrong with PHP’ sort-of misses the point. Yes, the language has weird bugaboos about it. All languages do. No, none of them are fatal. The language is easy to pick up and be productive in. It’s easy to have a mostly-static site with the odd dynamic page here and there. Deployment is a breeze. FTP up your new files and you’re done. You don’t even have to think about it. Sites run fast. Development is easy. The documentation is excellent. I haven’t seen any other environment that comes remotely close in that regard. Just about any thing you would want to be able to do, there is a function for. It exists to make dynamic web pages, so it fits that well.

The article also rather quickly breezes over an important point. Facebook uses PHP. Why is that? The article states that it’s fine for FB because they’re huge and can ‘engineer around’ the various weaknesses of the language. That certainly begs the question as to why they would bother. Is it just legacy? Are they just dumb? I have a hard time believing any of those possibilities.

Mass hosting for websites really only works for PHP. The security gets a little dodgy, but it basically kinda works. Try that with any other webdev environment and you wont get nearly the server-density that you do in PHP. That is pretty hard to beat.

Server-side includes. Anyone remember these? This is really what PHP has supplanted. For that kind of stuff, it’s great.

Or for a one-page site. Or a static site that has one dynamic page that does something – you cannot beat PHP.

Plenty of people use it with frameworks for complex sites. If I had a really super complex site to do, I honestly don’t know whether or not I’d do it in PHP. But if I did decide to do it there, I wouldn’t feel the least bit bad about it.

Edit, reload, etc. You can edit a PHP page on a server, hit reload, and it works. No magic. Or if there is magic in that, it’s so magical that you don’t need to ever know how it works. This is quite pleasant. No dicking around with production versus development or HUP signals or restart.txt files or any of that shit. On development or production; edit your file, reload. Boom.

Server infrastructure – since PHP is most often served up via Apache, you don’t have to throw some kind of reverse proxy in front of it or anything. If you have static assets, they will be quickly served up via Apache’s static web-page serving. All for free in the default set-up for PHP.

Performance. PHP is fast. Even without an accelerator. I’ve built many, many PHP apps, and I’ve never needed to use one – the database always ends up being the bottleneck, never the web front-end. It will likely outperform most other web environments with no tuning. I *have* had to tweak the maximum number of http processes in Apache on a very high-traffic site, and I’ve also messed with the maximum PHP memory to permit per-process, but (off the top of my head) those are the only two knobs I’ve had to twiddle. And I’ve only had to do that on sites with the highest-of-traffic running on the crappiest-of-server environments.

So if you want to live in your tiny ivory tower and yammer on endlessly on pedantic points about object hierarchies and namespace pollution and function-name consistency, feel free. However, those of us who are jamming out PHP sites will not be doing that – because we will have already finished the project we’ve worked on and moved on to the next one.