我目前正在优化PHP应用程序,发现一个函数被调用大约10-20k次,所以我想我会在那里开始优化:
function keysToLower($obj)
{
if(!is_object($obj) && !is_array($obj)) return $obj;
foreach($obj as $key=>$element)
{
$element=keysToLower($element);
if(is_object($obj))
{
$obj->{strtolower($key)}=$element;
if(!ctype_lower($key)) unset($obj->{$key});
}
else if(is_array($obj) && ctype_upper($key))
{
$obj[strtolower($key)]=$element;
unset($obj[$key]);
}
}
return $obj;
}
大部分时间花在递归调用上(在PHP中速度很慢),但我没有看到任何方法将其转换为循环。 你会做什么?
此版本不考虑关联数组,因为我的数据没有,但比原始版本快近10倍。大部分工作都是由Gumbo完成的,主要的加速来自于使用引用和创建新对象而不是取消设置旧密钥。
function &keysToLower(&$obj)
{
if(is_object($obj))
{
$newobj = (object) array();
foreach ($obj as $key => &$val)
$newobj->{strtolower($key)} = keysToLower($val);
$obj=$newobj;
}
else if(is_array($obj))
foreach($obj as &$value)
keysToLower($value);
return $obj;
}
答案 0 :(得分:5)
Foreach
正在使用随后遍历的内部副本。不用尝试:
function keysToLower($obj)
{
$type = (int) is_object($obj) - (int) is_array($obj);
if ($type === 0) return $obj;
reset($obj);
while (($key = key($obj)) !== null)
{
$element = keysToLower(current($obj));
switch ($type)
{
case 1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj->{$key});
$key = $keyLowercase;
}
$obj->{$key} = $element;
break;
case -1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj[$key]);
$key = $keyLowercase;
}
$obj[$key] = $element;
break;
}
next($obj);
}
return $obj;
}
或使用引用来避免使用副本:
function &keysToLower(&$obj)
{
$type = (int) is_object($obj) - (int) is_array($obj);
if ($type === 0) return $obj;
foreach ($obj as $key => &$val)
{
$element = keysToLower($val);
switch ($type)
{
case 1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj->{$key});
$key = $keyLowercase;
}
$obj->{$key} = $element;
break;
case -1:
if (!is_int($key) && $key !== ($keyLowercase = strtolower($key)))
{
unset($obj[$key]);
$key = $keyLowercase;
}
$obj[$key] = $element;
break;
}
}
return $obj;
}
答案 1 :(得分:3)
您可能还想查找array_change_key_case()
答案 2 :(得分:2)
我假设你不关心转换为数组......
function keys_to_lower($o) {
if (is_object($o)) {
$o = (array)$o;
}
if (is_array($o)) {
return array_map('keys_to_lower', array_change_key_case($o));
}
else {
return $o;
}
}
答案 3 :(得分:2)
这里使用lambda的例子:
$multiArrayChangeKeyCase = function (&$array) use (&$multiArrayChangeKeyCase) {
$array = array_change_key_case($array);
foreach ($array as $key => $row)
if (is_array($row))
$multiArrayChangeKeyCase($array[$key]);
};
答案 4 :(得分:1)
array_combine(array_map("strtolower", array_keys($a)), array_values($a))
答案 5 :(得分:0)
对旧线程有一些较晚的响应,但是有一个本机函数可以执行此操作,您可以按照以下方式将其包装起来。
function setKeyCasing($thing, $case = CASE_LOWER) {
return array_change_key_case((array) $thing, $case);
}