foreach - это наиболее часто применяемая конструкция в PHP, но в некоторых случаях обхода массива гораздо оптимальнее использовать связку array_walk + анонимную функцию.
Рассмотрим это дело на примерах.
1/ Первый пример, в нем сразу куча неоптимальных моментов.
// Создаем массивы
$arrayAfter = array();
$arrayBefore = array('John Doe', 'Michael Smith', 'Alice Staples');
// Поехали бежать по массиву
foreach ($arrayBefore as $element) {
// ненужная переменная, она будет доступна ниже по коду!
$someLocalIterateVariable = 'bla-bla-bla';
$element = preg_replace('/[^A-Za-z0-9-]+/', '-', $element);
$element = strtolower($element);
$arrayAfter[] = $element;
}
// Выводим итоговый массив
// Array ( [0] => john-doe [1] => michael-smith [2] => alice-staples )
var_dump($arrayAfter);
// как видно, ненужная переменная итерации сохранилась:
var_dump($element);
// как видите, переменные, нужные только в теле foreach засоряют ниже лежащий код
var_dump($someLocalIterateVariable);
2/ Можно еще так данный код переписать, но тоже это не оптимальный вариант:
$arrayBefore = array('John Doe', 'Michael Smith', 'Alice Staples');
foreach ($arrayBefore as &$element) {
$element = preg_replace('/[^A-Za-z0-9-]+/', '-', $element);
$element = strtolower($element);
}
// Выводим итоговый массив
// Array ( [0] => john-doe [1] => michael-smith [2] => alice-staples )
var_dump($arrayBefore);
// как видно, ненужная cсылка на переменную сохранилась
var_dump($element);
// случайно можем ее поменять
$element = 123;
// и получить неожиданность в массиве:
// Array ( [0] => john-doe [1] => michael-smith [2] => 123 )
var_dump($arrayBefore);
3/ На много более красивый и оптимальный пример кода:
// Создаем массив
$arraySlugs = array('John Doe', 'Michael Smith', 'Alice Staples');
// эту переменную передадим в анонимную функцию
$suffixName = ' person';
$suffixName2 = ' person2';
// обратите внимание, как use я передаю в итерацию возможно необходимые переменные
array_walk($arraySlugs, function(&$element) use ($suffixName, $suffixName2) {
// ненужная переменная, она не будет доступна ниже по коду!
$someLocalIterateVariable = 'bla-bla-bla';
$element = preg_replace('/[^A-Za-z0-9-]+/', '-', $element);
$element = strtolower($element);
$element .= $suffixName;
});
// выводим массив
var_dump($arraySlugs);
// NULL
var_dump($someLocalIterateVariable);
// NULL
var_dump($element);
Такой код оптимален по многим параметрам: 1. переменные в итерации не засоряют нижележащий код 2. Такой код выполняется быстрее (это не всегда так, см. комментарии), чем foreach и потребляет меньше памяти (см. п.1)
Весьма рекомендую задуматься и пересмотреть случаи использования foreach и array_* + function().
Иван, я имел в виду массив $IBLOCK_CACHE_PROPERTY целиком закэшировать в одном элементе кэша (в случае файлового хранения - один файл). А вот размер - да, для крупного проекта, где очень много свойств не подойдет наверно, нужно тестировать. В моем проекте свойств примерно 500. Что дает примерно полмегабайта сериализованного кэша. Чтение такого объема пройдет мгновенно, потому как memcache. А вот его десериализация не знаю как скажется на производительности.
Пилецкий Антон, я наконец понял идею. Да, на проекте с ограниченным количеством свойств это будет работать и, скорее всего, окажется проще в реализации. Однако, при ближайшем рассмотрении, мое решение кажется мне более оптимальным, так как глобальный массив никогда не будет содержать больше элементов, чем требуется скрипту для обработки конкретного запроса. В предлагаемом же варианте, если рассматривать худший сценарий, массив $IBLOCK_CACHE_PROPERTY будет фактически дублировать таблицу b_iblock_property. Причем, заполняться он будет даже на тех страницах, где в нем нет необходимости.
Тем не менее, спасибо за идею. Такой подход может оказаться полезным в аналогичных ситуациях. Обязательно его запомню.
Пилецкий Антон, этот "облом" обходится на этапе 2 из моего оригинального сообщения. Достаточно создать объект CIBlockProperty, что приведет к однократному подключению файла iblockproperty.php и инициализации массива. После этого $IBLOCK_CACHE_PROPERTY можно переопределять как угодно.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».