[wp-hackers] PHP4->5 upgrade heads up
Brian Layman
Brian at TheCodeCave.com
Thu Jul 13 21:55:54 GMT 2006
On a related topic, I've been meaning to mention the widgets problem I'd
discussed with Andy Skelton. In the end it was related to the change in
array_merge between PHP4 and PHP5 and could occur in anyone's code. So, if
someone missed this array_merge change, I thought a public post might be
beneficial...
PHP5's array_merge now blows up on non-array variables. It seems some PHP
array functions, specifically array_slice, return non-array (unset)
variables. So, in short, an array_merge that works in php4 may not work in
php5 unless you follow the same convention Mark Jaquith recommended when he
said "cast to array before foreach".
If a variable's content hasn't already been verified as containing an array,
you should cast to array before using it in an array_merge.
That could look like this:
$result = array_merge(array('a'=>1,'b'=>2), (array) $second);
Details on the change can of course be seen here:
http://us2.php.net/array_merge
I'm sure this is old news for some. So, unless you want details of what we
changed, you probably won't care to read on.
----
For a practical example, we could look at the now fixed issue from
widgets.php.
An array slice was done in a fashion similar to this:
$registered_widgets[$name]['params'] => array_slice(func_get_args(), 2)
We are assuming that the problem arose when the 2 argument was defaulted to
''.
The line that actually blew up was this one:
$params = array_merge(array($sidebar),
$registered_widgets[$name]['params']);
The error was:
"Warning: array_merge() [function.array-merge]: Argument #2 is not an array
in ./wp-content/plugins/widgets/widgets.php on line 154"
There is nothing that indicates array_slice changed between 4 and 5. So, it
appears the only difference was in array_merge. Wrapping the error line in
an "if (is_array($registered_widgets[$name]['params']))" solved the problem,
but it was not the fix we used.
I remembered Mark's coding style suggestion for foreach in
(http://comox.textdrive.com/pipermail/wp-hackers/2006-July/006930.html) and
applying it solved the problem in a simpler fashion. Andy checked in this
new line:
$params = array_merge(array($sidebar), (array)
$registered_widgets[$name]['params']);
FYI, we'd tried this first:
$registered_widgets[$name]['params'] => (array)
array_slice(func_get_args(), 2)
but it had no affect.
-
I looked at every instance of array_merge in the 2.03 code, and it seems
that all of them are in places where the parameters are guaranteed to have
either a value or array() specified. So, this is mostly a heads up to
plugin authors. I haven't done any examination of the plugin code base.
More information about the wp-hackers
mailing list