There are several functions which should be improved:
- Some of the functions are recursive, but can be easily changed to non-recursive implementation
- Some of the functions have side effects when they unexpectedly (and unnecessary) modify parameters passed by reference
- Optimizations are possible if we lightly modify the behavior (e.g. parameters handling or return values)
Let's look at getElement() as an example:
public static function getElement(&$array, array &$keys, $value = null)
{
if (count($keys)) {
$key = array_shift($keys);
return isset($array[$key])
? self::getElement($array[$key], $keys, $value)
: false;
}
if (!is_null($value)) {
$array = $value;
}
return $array;
}
-
The function modifies $array contents, but only if $value is not null.
Proposal: Drop $value parameter from getElement(). Use setElement() for the only case in Horde_Form_type_image::getUploadedFileType() where the $array is modified.
-
The function modifies $keys array (removes all elements). This is an unneeded side effect, and it looks like existing code does not rely on it anywhere.
Proposal: Remove & from &$keys.
-
The function is recursive.
Proposal: Make it non-recursive.
-
In some existing case(s) it would be beneficial to support a case when $keys is a string with a single key.
For example, in Horde::getDriverConfig($backend, $type = 'sql')):
if (is_array($backend)) {
$c = Horde_Array::getElement($conf, $backend);
} elseif (isset($conf[$backend])) {
$c = $conf[$backend];
} else {
$c = null;
}
Proposal: Support string in $keys parameter. Additionally, if we modify getElement() to return null instead of false for non-existent properties, then the above snippet could be simplified to just this:
$c = Horde_Array::getElement($conf, $backend);
And it looks like this will not cause issues with the existing code. Here is one place in Horde_Core_Perms::getAvailable() where the return value is checked for false:
$children = Horde_Array::getElement($perms['tree'], $levels);
if (($children === false) ||
!is_array($children) ||
!count($children)) {
/* No array of children available for this permission name. */
return false;
}
If returned value becomes null instead of false, it still would still trigger !is_array() check (but we could also adjust the code).
With the above proposals the getElement() function transforms into this:
public static function getElement($array, $keys)
{
$ref = &$array;
foreach ((array) $keys as $key) {
if (!isset($ref[$key])) {
return null;
}
$ref = &$ref[$key];
}
return $ref;
}
Other functions should be modified in similar way.
There are several functions which should be improved:
Let's look at
getElement()as an example:The function modifies
$arraycontents, but only if$valueis notnull.Proposal: Drop
$valueparameter fromgetElement(). UsesetElement()for the only case inHorde_Form_type_image::getUploadedFileType()where the$arrayis modified.The function modifies
$keysarray (removes all elements). This is an unneeded side effect, and it looks like existing code does not rely on it anywhere.Proposal: Remove & from
&$keys.The function is recursive.
Proposal: Make it non-recursive.
In some existing case(s) it would be beneficial to support a case when
$keysis a string with a single key.For example, in
Horde::getDriverConfig($backend, $type = 'sql')):Proposal: Support string in
$keysparameter. Additionally, if we modifygetElement()to returnnullinstead offalsefor non-existent properties, then the above snippet could be simplified to just this:And it looks like this will not cause issues with the existing code. Here is one place in
Horde_Core_Perms::getAvailable()where the return value is checked forfalse:If returned value becomes
nullinstead offalse, it still would still trigger!is_array()check (but we could also adjust the code).With the above proposals the
getElement()function transforms into this:Other functions should be modified in similar way.