Published by Fabian on 25 Mar 2008
PHP function backporting nightmare
While reading a the ZCE certification book I came along some oddities, which I also noticed before but couldn’t get the full picture.
When looking at PHP code you will come at some point to code that looks like this:
if (function_exists('str_split')) { $var = str_split($input); } else { // custom code taken from php.net or brain $var = $temp }
The code exists, because the developer found a nice functionality on the manual, but unfortunately noticed that it requires a bleeding edge PHP version or some special modules installed. But instead making this a requirement for his application/component to run he takes one of the plenty: “what if this is not available” workarounds from php.net manual comments. However these are mostly not so good, which you cane notice because each one will get multiple corrections.
So how to do it in a better way? You might need tis functionality also somewhere else, so please don’t start code duplication.
Some comments on php.net already suggest doing that, but not all yet, so here a proposal for better maintainability:
Somewhere in you code write
if (!function_exists('str_split')) { function str_split($text, $split = 1) { // custom code taken from php.net or brain return $temp; } }
Thats good. Nowhere in you code you need to do ifs anymore, just use the method.
But doesn’t that come with a performance hit? Yes. It comes with a hit on versions lacking the method, even worse, it comes with a hit on versions having that method.
So I do recommend to put this into an extra file, remove the if check and document that your customer has to include that file if he is running an older version (Or better, add it to troubleshooting as well under headline “I get function not defined error”).
Even better, if you are convinced of this idea now, be prepared for: PEAR::PHP_Compat which exactly is this. So for php version mismatches a solution is found. For not (yet) installed packages: do the same. Write compat method in separate file and ask the customer to either include the compat file or install the real thing from module.
My main message is: do not spoil your code with compatibility and corner case solutions. Externalize and document them.
And check the php.net comments regularly to see if somebody corrected the workaround-solution someone posted some time ago, or found a critical security issue in it or something else