Archive for the ‘Rant’ Category.

Global variables in WordPress

[WordPress logo][wordpress] In my critique of the code in WordPress I talked about the frequent use of global variables, something this I think it a bad practice. In response Owen Winkler writes that:

Global variables are used in WordPress in many places to make things simpler for a novice end-user to design. [...]

The point is that novice plugin and template designers shouldn’t have to worry about object-oriented syntax, and therefore lots of object members are put into the global scope.

It might be easy, but I still find this a poor way to pass information around in an application. The global variables obscure the relationship between functions. Take my example from the original rant, the mysql2date() function — it’s the second function (or third, depending on whether or not you expect Gettext to be active) in wp-includes/functions.php.

The first line in the body declares four global variables named $month, $weekday, $month_abbrev, and $weekday_abbrev. So this function is obviously somehow dependent on those variables being initialized. So the first question is: can I always call mysql2date()? Do I first have to call some initialization function, or is this guaranteed to be done for me when I want to use mysql2date() in some plugin or template?

It’s not such a big mystery to figure out where the variables come from: a quick grep reveals that they are defined in locale.php. But who takes care of including locale.php? Another grep, and one sees that this is done by wp-settings.php — I guess that file is always loaded, and thus one can be sure that $month and the other globals are indeed initialized before a call to mysql2date().

No wait! On close inspection of wp-settings.php one sees that locale.php is loaded after the active plugins are loaded, and after a call to do_action('plugins_loaded'). So does this mean that a

plugin that attaches itself to the plugins_loaded action cannot call mysql2date()? I believe it does!

In my installation I found no other references to the plugins_loaded action, and so this could explain why this bug wasn’t found earlier. But in any case — if the developers had taken the time to properly document this dependency between locale.php and functions.php, then the problem should never have occurred in the first place.

This potential bug wasn’t the reason for my initial worries about the use of global variables: I had been trying to get the Smart link plugin working. It uses a global $comments variable to know which comments to process, but the comments.php template doesn’t define it to be global — in fact the $comments variable is a local variable in the comments_template() function in comment-functions.php. This function includes comments.php, and thus $comments has the local scope in that file. (These scope rule games in PHP are just so annoying!)

I now see that the problem that triggered my anger against the global variables was in fact a use of a non-global variable, expecting it to be global. A bit ironic that I were to find a problem with a totally different function, mysql2date(), while initially being started by a mistake in a plugin…

Feedback on my rant

My rant about the quality of the WordPress code caused some discussion, both here and on the WP hackers mailinglist.

I understand if my comments seemed harsh, especially because I’m quite new to [WordPress][], but I still think they were justified. Especially the point about having comments in the code, where I think that (I’m quoting myself here):

[...] the idea that there can be such a thing as well-written code containing no comments is bogus: it is only in small toy examples that the function and argument names are enough to determine what a function does.

Comments are very important in a weakly-typed language like [PHP][] where you cannot tell anything at all from looking at the function.

WordPress code quality

WordPress logo WordPress calls itself a “state-of-the-art semantic personal publishing platform” — but the engine that lies beneath this shiny, smooth-looking CSS-styled surface is not that nice.

I find the coding standard in the current (version 1.5.1.1) code to be below what I would expect from a piece of software as popular as WordPress:

  • Global variables are used all over the place! Global variables should be used sparsely, if at all, for they often make the code more difficult to understand. Other people agree that Global Variables are Bad.

    From looking through the code I’ve found a $wpdb variable which is used as a global handle to the database. That’s fair enough — such a handle is needed, and lots of different pieces of the code need access to it. But still it could be handled better if one consistently used $GLOBALS['wpdb'] instead of global $wpdb followed by a later use of just $wpdb — by using the $GLOBALS array one precisely describes that this variable is just that: global.

    There are also lots of other global variables in the code, and they are often used in a much more subtle way than the $wpdb variable. A simple count of the (unique) variables declared global in the wp-includes directory gives no less than 108 variables!

  • Lack of comments! The core files such as functions.php contains tons of functions, but no comments. Take a random function like mysql2date() with a signature of

    function mysql2date($dateformatstring, $mysqlstring, $translate = true)

    is hard to understand without reading the code. The source has no doc comments which describe the arguments or the result type.

    The online documentation website, the Codex, is still very incomplete when it comes to information about the internals, and I would much prefer to have the documentation right there where it’s needed: in the code.

  • Duplicated code! Why does the code in post.php not use the wp_insert_post() function declared in functions-post.php? Instead it seems to duplicate the logic in wp_insert_post(), something which will sooner or later lead to problems.

  • Incredibly long lines! It is clear that there has been made no attempt to break the code into lines at a reasonable site (that is, less than 80 characters per line).

    Those long lines makes the code annoying to read unless I make my terminal or Emacs huge and it makes diffs cryptic when one has to compare two 200 character lines to figure out a change. For someone who would like to look into the code those things make a real difference and should not be neglected because it is “just cosmetics”.

  • Mixed XHTML and PHP code. The themes in WordPress use no page template system what so ever, they just output the raw XHTML to the user — making it easy to create invalid XHTML output.

    To defend this choice, then I must say that I’ve never been impressed by template systems like Smarty which claims to separate the application code from the presentation. To do this they give you a template language in which you can program your pages — if you look more closely at it, then this template language ends up being simply a reimplementation of the original language. So instead of if ($foo || $bar) ... you write {if $foo or $bar} .... Has this bought you anything, except requiring you to learn another language with its possible quirks and limitations?

    If that was what the WordPress developers asked themselves, then I can understand why they simply went with normal PHP code mixed with XHTML. But it can be done better than that: PhpWiki uses a cool system where all the XHTML code is generated using a set of classes and functions. Using such a high-level interface automatically makes the produced XHTML code compliant and it makes the source so much cleaner. With some proper caching the performance shouldn’t be affected, but the long term quality of WordPress would improve.

I hope that the WordPress developers take steps to fix and improve some of the things I’ve described above. Apparently, there are others who agree with me about the quality of the WordPress code. Despite my complains, I’ll keep using it, for even though I can find lots of things to complain about, I still think it’s the best software for what it does.

Finding a cheap PHP5 host

I’ve been looking for a hosting provider that would give me PHP5 at a decent price. NETsite have already upgraded to PHP5, but they’re somewhat expensive, demanding 111 DKK (about 15€) a month. There are plenty of other Danish hosting providers that will give me much more space for far less money.

Finding someone who can provide PHP5 is rather difficult. Neither FastTech, Webdomain, freepaq, NeedHost, nor Dkx can provide a PHP5 solution… At Powerhosting I could buy my own server and then get PHP5 on it, but it would be more expensive than staying with NETsite.

At ComSupport Gruppen they are waiting for official Debian of PHP5 — but those packages have been stalled for over six months now… It’s a bit unclear why Debian hasn’t got any PHP5 packages by now, especially since Piotr Roszatycki uploaded them a couple of months ago. But apparently they weren’t acceptable to the ftpmasters. But instead of working on getting the packages acceptable things just stopped :-( I think that’s rather sad… Debian is about to release Sarge, and having PHP5 in it would be a nice plus, especially if it would mean that people would upgrade to it.

Slow printing

Today I tried to print some of the slides and papers that I need to read for the courses at the ETH. Compared to the printing at DAIMI I find printing here at the ETH very slow.

The rule seems to be that you submit your print job to the printer via the VPP system (a nifty abbriviation standing for both “Versatile Printers and Plotters” and “Verteilte Printer und Plotter”) and then you wait… and wait… and then perhaps half an hour later you will be able to pickup the result of your waiting: your document printed on slightly gray recycled paper.

I don’t really mind the paper that much — we don’t pay for it, so it’s okay that it’s not pure white — but the amount of time one has to wait is a bit too much. Maybe it’s just because of bad memory, but when I think back to how it was at DAIMI, then I believe things went faster there.

Another slightly annoying thing about this VPP system is, that I haven’t yet figured out how to print from the Linux and Solaris systems they have installed here at the ETH. At DAIMI it was as easy as lpr -P stibitz-115 file.ps but as far as I’ve understood the VPP system then it isn’t that easy. But at least I can print from Windows in the mean time…

Oh! — my two print jobs have finished: 22 minutes for the first and 27 minuttes for the second job.