Intereting Posts
Запретить IIS изменять ответ при наличии заголовка местоположения Загружать файлы из IPhone / IPad в базу данных mysql? Установка nodeValue DOMelement: ошибка: попытка получить свойство не объекта Моделирование объектов с несколькими отношениями таблиц в Zend Framework Как проверить ввод формы на одной странице с помощью случайных чисел? Советы по экономии времени загрузки страницы Есть ли способ ограничить количество представлений для php-формы? Laravel: узнайте, является ли переменная Как изменить размер изображения в php, чтобы поместить его в ящик нестандартного размера, сохраняя его соотношение сторон? Unescape или html-декодирование в Twig (PHP Templating) Простой вопрос чтения XML (PHP) Уникальные идентификаторы в таблице соединений symfony2 Метод blade.php, выводящий результат в форму Предотвращение прямого доступа к файлу, вызываемому функцией ajax Как заставить пользователей получать доступ к моей странице через HTTPS вместо HTTP?

Преобразование ключей массива / дерева объектов в нижний регистр

В настоящее время я оптимизирую приложение PHP и обнаружил, что одна функция вызывается примерно в 10-20 тыс. Раз, поэтому я подумал, что приступим к оптимизации:

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; } 

Related of "Преобразование ключей массива / дерева объектов в нижний регистр"

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; 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; 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; } с 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; } с 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; } 

Вам также может понадобиться lookup array_change_key_case ()

Я предполагаю, что вы не заботитесь о литье в массив …

 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; } } 

здесь пример использования лямбда:

 $multiArrayChangeKeyCase = function (&$array) use (&$multiArrayChangeKeyCase) { $array = array_change_key_case($array); foreach ($array as $key => $row) if (is_array($row)) $multiArrayChangeKeyCase($array[$key]); }; 
 array_combine(array_map("strtolower", array_keys($a)), array_values($a))