[
][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…