As part of my “speeding up my blog” series, I planned to write a nice, informative post about upgrading to WordPress 3, deploying your theme to a CDN, and getting it all running under nginx. Unfortunately WordPress irritated me so much in the process, that this has turned into more of rant. Sorry in advance.
I have a like/hate relationship with WordPress. That is to say that it does a lot, it has a great admin area and there’s a large community producing themes and plug-ins. However, I am a PHP developer of many years, and every time I come into direct contact with the core WordPress code-base I end up being sick in my mouth.
What’s to hate? Well it kind of reminds me of that old BMW advert (or was it Audi?) the one with the swan – On the surface it glides effortlessly, but under the water it’s an ugly son of a bitch, churning away to get the job done. I had the misfortune of working on a nasty WPMU project last year and found myself looking under the bonnet more than was good for me. Not only is WordPress a horribly written piece of PHP, (and possibly responsible for many a bad word said about PHP itself) it has a legacy of incremental improvements alongside a legacy of community-contributed code that strives to remain as reverse compatible as possible.
If you don’t want to read my rantings, skip to the bit at the end, otherwise … WordPress, let me count the ways a hate thee.
1. Base URL hell
I wanted to get as much of my static assets onto a CDN as I could – a topic I’ll cover in full later. This means serving static files (such as images and css) from a different base URL. It should be simple to upload your theme and plug-in directories to another server and ensure that WordPress points to the correct assets in your HTML. It is not simple. Just look at the hideousness of determining base URLs in WordPress. This simple task should not require a complex plug-in to cover all possible legacy issues. Furthermore, WordPress allows all plug-ins to mess around with base URLs, which means one plug-in might completely undo the work of another.
Oh, by the way – WordPress defines the constant WP_CONTENT_URL
before it loads any plug-ins, so the only way to override this is to define it in wp-config.php
.
2. Canonical domain ridiculousness
If you access a WordPress site from a domain that is not hard-wired into the site’s database, it will redirect you to the ‘correct’ URL. This is the default behaviour. So, if you want to host the same exact site from a different domain, or different port, (e.g. for debugging a distributed system) you will have to write a WordPress plug-in to override this behaviour. Why does this annoy me?
- It is not PHP’s job to decide what domain a site lives on – that is the job of the web server. A domain redirect like this should be done at server config level.
- No system should hard-wire its domain into database-saved preferences. This is nuts, and WordPress does it in multiple places.
3. Magic quotes are the Devil\’s work
Magic quotes are so utterly evil that they have been removed from PHP 5.3. They are testament to the amateur reputation of PHP. However, even in earlier versions of PHP, magic quotes could be easily disabled, and anyone who knows what they’re doing with PHP will have been doing so for years. Furthermore any system written properly would insist on them being disabled. Not so with WordPress. In fact, being able to disable magic quotes poses a problem for WordPress. How can it guarantee to work if you can forcibly disable magic quotes?
Answer: By forcing them even more forcibly. WordPress 3 forces all script input through its own wp_magic_quotes
function. Funnily enough this isn’t documented, but it looks like this.
4. mysqli support – or not.
The core WordPress code-base uses the old mysql database driver. When I say old, consider that the mysqli (improved) extension was introduced for versions of MySQL > 4.1.3 in PHP 5, which came out of beta in 2004. WordPress does have a drop-in replacement system though, which allows you to place your own db.php
file in wp-content
. Here’s the third-party-developed mysqli adapter for WordPress that I am using on this site.
So that’s okay then, right? Well, judging by the required location for the db.php
file, this adapter system looks rather like an after-thought. Using the alternative database adapter means calling require_wp_db()
rather than just including the original wp-includes/wp-db.php
file. Great – except is every plug-in out there doing this? Even WordPress itself isn’t fully patched to support this. At the time of writing, the “famous 5-minute installer” uses the mysql adapter only – I had to patch wp-admin/install.php to be able to install WordPress with only mysqli on my system.
5. Depreciated code handling
Watch out for depreciated function names. For example: WordPress changed wp_specialchars
to esc_html
. This will result in notices being raised in older themes, which you’ll only see if you enable WP_DEBUG
. It’s a good idea to find-and-replace these if you’re upgrading an old theme to WP3. I don’t really hate WordPress for this, but it seems a bit of a pointless change, and isn’t it a bit late in the day for being pedantic about naming conventions? A whim like this just contributes to the amount of legacy in the system and the amount of code devoted to handling depreciation. There’s a 2,500 line file devoted to depreciating functions that are to be removed “later”. Making a clean break with WordPress 3 would have prevented many people from upgrading, so I understand why they do this; I just don’t like the effect it has on the code-base.
I could go on, but I’m hungry. If you want more, see what this guy has to say on the topic.
The bit at the end
All in all, I’m disappointed that WordPress 3 wasn’t taken as an opportunity to improve upon its own legacy. It is fairly clear that popularity with amateurs, ‘ease of use’ and backward compatibility is more important to the team than creating good, robust software that developers will appreciate. Drupal sets a much better example. I’m not saying I don’t have any gripes with Drupal, but they are much happier to take reduced backward compatibility on the chin when they release new versions. This means more incompatible modules, but such is the price of progress.