I recently put new releases of my Twitter Tools plugin – basically patches so that it would work in WordPress 2.9 on versions of PHP prior to 5.2. This is an interesting situation, where I hadn’t really done anything wrong in the plugin and the WP core team hadn’t really done anything wrong in the way they implemented their JSON functionality for versions of PHP prior to 5.2. It just happened that the bits of code weren’t compatible with each other.
Sure it was frustrating. I was in a situation where there was a bit of public outcry about my plugin being “broken”. All of a sudden, something that used to work fine didn’t (for some). The result? I spent a good deal of time debugging an issue with my plugin that I didn’t cause and couldn’t reproduce.1 However when you step back and look at the situation, I’m not sure there is a clear-cut target to blame here. Everyone’s intentions were pure. The point is, this is an interesting case study and one that both the WP plugin and theme devs and the WP Core devs can learn from.
Situation
Versions of PHP prior to 5.2 do not include native functions for encoding and decoding JSON formatted data.
The solution in Twitter Tools prior to the releases last weekend: include a PHP library (Services_JSON) along with the plugin, wrap it in a check to make sure that it isn’t already included, and use it instead of the native PHP functions.
The solution in WordPress 2.9: define the equivalent versions of the native PHP encode and decode functions in the core, include a PHP library (Services_JSON) in those functions and load it if needed.
So we had a situation in some WordPress server configurations where my plugin loaded the library, then WP core tried to load the same library and PHP didn’t like that very much.
The WP 2.9 solution provides us with an interesting situation. I still wanted to support versions of WP prior to 2.9, which means I still need to include my copy of the library. However I also don’t want it to break in 2.9, so I need to make my inclusion of the library compatible with the WP 2.9 approach.
Solution
Use the same approach in my plugin that WP 2.9 does. WP 2.9 checks to see if the PHP function json_encode(), etc. exists, and defines it if it doesn’t. If Twitter Tools does the same thing and loads after the WP version (which is loaded from compat.php), it will only define those functions and include the library as needed. Based on feedback, this approach is working for both pre-2.9 versions of WordPress and WP 2.9.x.
Lessons
Plugin/theme devs, be careful when including a compatibility library that might get added to WP core in the future. Try to structure your code in such a way that it will continue to work even if this happens.
WP core devs, when adding a library consider the plugins that might already be including that library and do so in a way that lets everything continue to work.
Why wasn’t this caught in beta testing of WordPress 2.9? It’s pretty simple – even though I tested some of my plugins in pre-releases of 2.9, I did not test them with older versions of PHP (required to trigger this bug). I’m guessing that most of the developers that were beta testing were also running new versions of PHP. A true application testing matrix is not realistic for WordPress + plugins + themes.
Take a look at the diff for an example, I think this technique is portable to other plugins that may experience this same problem.
Also, I created a ticket in Trac to try to make this work a little more smoothly going forward. Thanks to the core team for accepting the patch.
- Trying to patch a problem that you can’t reproduce will inevitably require a few point release. 😉 [back]
This post is part of the project: Twitter Tools. View the project timeline for more context on this post.
The systems engineer in me looks at problems like these and just sighs. It makes me want to be a completionist about testing, but I can’t even begin to figure out how many variables there might be.
[…] WordPress 2.9 and PHP Libraries | alexking.org (tags: gfmorris_comment) Posted January 13th, 2010 in del.icio.us Links by del.icio.us Linkdumper. […]
[…] WordPress 2.9 and PHP Libraries | alexking.org […]
We faced the exact same issue with the JSON library suddenly appearing for the IntenseDebate plugin, and we’re solving it in the same way.
I thought I was loading JSON in a “safe” way before, but apparently it wasn’t quite “safe enough” 😉
Thanks for the detailed write-up that explains the situation succinctly.
Having thought about it more, I actually have a more succinct summary:
I was conditionally loading Services_JSON in my plugin. WordPress 2.9 was lazily loading it unconditionally. The two approaches are not compatible. 🙂
I’m not sure if I’m understanding this fully…
So does this mean that, if I don’t want to support any pre-2.9 versions of WP, I can just use the PHP-native JSON functions and it will just fake them?
If so, awesome!
Yes, though the implementation is not 100% compatible with the native PHP functions. For example, you can’t specify the return as an array instead of an object.
Oh well, you can’t have everything. 🙂 I like that they’re trying to supply some tools to help us deal with the continued PHP support though…
[…] WordPress 2.9 and PHP Libraries […]
This is interesting, because I believe the same bug has hit the P2 theme, created by the same WP folks, and they have yet to fix it. See the thread here:
http://wordpress.org[...]7?replies=37
I wonder how many other plugins/themes this has affected.
I’ve run into all sorts of issues like this with my Fotobook plugin. I’m conditionally including the Facebook libraries only when the plugin actually needs them, but many of the other Facebook plugins include them across the board, without any checks to see if they already exist. Frustrating…