Разберем основные приемы оптимизации от простого к сложному.

Избавляемся от «магических» поисков (isset vs array_key_exists)
Интерпретатор тратит время на поиск ключей.
- Плохо:
array_key_exists($key, $data). Эта функция ищет ключ по всему хэш-таблице массива. - Хорошо:
isset($data[$key]). Это языковая конструкция. Она проверяет существование переменной и то, что она не null, делая это на уровне ядра виртуальной машины гораздо быстрее.
ВыделитьPHP
// Медленно (функция)
if (array_key_exists('id', $_GET)) { ... }
// Быстро (языковая конструкция)
if (isset($_GET['id'])) { ... }Циклы: Вычисляй заранее
Самая частая ошибка новичков — вызов функций внутри условия цикла.
Пример плохого кода:
ВыделитьPHP
for ($i = 0; $i < count($items); $i++) {
// обработка
}Здесь PHP на каждой итерации заново вызывает функцию
count(), чтобы посчитать длину массива. Если там 10 000 элементов, ты делаешь эту работу 10 000 раз.Оптимизированный вариант:
ВыделитьPHP
$total = count($items);
for ($i = 0; $i < $total; $i++) {
// обработка
}Или еще лучше — использование
foreach, где движок сам кэширует размер:
ВыделитьPHP
foreach ($items as $item) {
// обработка
}Строки: Точка против запятой
Вывод через
echo ведет себя по-разному в зависимости от разделителя.
Когда ты используешь точку
., PHP сначала склеивает строки в одну новую временную строку в памяти, а потом выводит её. Когда используешь запятую , — он просто отправляет аргументы в буфер вывода по очереди.
ВыделитьPHP
$str1 = "Привет";
$str2 = "Мир";
// Создает временную строку "Привет Мир" в памяти
echo $str1 . ' ' . $str2;
// Просто шлет два значения в output buffer без лишнего копирования
echo $str1, ' ', $str2;На больших объемах данных разница становится заметной для сборщика мусора.
Классы и свойства: Скрывай меньше
Для работы с приватными (
private) или защищенными (protected) свойствами класса интерпретатор вынужден делать дополнительные проверки прав доступа при каждом обращении (стеки фреймов видимости). Публичные свойства доступнее.Однако современный подход требует использования типов (Type Hinting). Начиная с PHP 7.4 появились Typed Properties. Они позволяют объявить тип прямо у свойства. Для JIT-компилятора (в PHP 8.x) это манна небесная: ему не нужно гадать, число там или строка, он генерирует оптимизированный машинный код сразу.
ВыделитьPHP
class User {
// Старый стиль (медленнее из-за проверок динамичности)
public $name;
// Современный стиль (быстрее благодаря строгой типизации)
public string $email;
public int $age;
}Подводные камни: Что убивает производительность
Даже если твой алгоритм идеален, есть функции-пожиратели ресурсов:
@(Оператор подавления ошибок). Никогда не используй его. Чтобы скрыть ошибку, PHP создает специальный контекст выполнения, переключает уровни логирования и обрабатывает исключение. Это замедляет выполнение в десятки раз.eval()и создание функций на лету (create_function). OPCache (кэшер опкода) не может закэшировать код внутри eval. Каждый раз эта строка парсится и компилируется с нуля. Кроме того, это дыра в безопасности.- Регулярные выражения. Используй
preg_*только тогда, когда простые строковые функции (strpos,str_replace,explode) не справляются. Поиск подстроки через strpos работает на порядки быстрее, чем сложный PCRE-машину регулярных выражений.
Инфраструктурная оптимизация (OPcache)
Самый мощный способ ускорить PHP версии 5.5+ и всех версий 8.x — включить OPcache. Он сохраняет скомпилированный байткод в оперативной памяти. При следующем запросе серверу не нужно читать файл с диска и превращать его в команды — он берет готовое из RAM.
Настройки в php.ini для продакшена:
ВыделитьINI
opcache.enable=1
opcache.memory_consumption=256 ; выдели достаточно памяти
opcache.max_accelerated_files=20000
opcache.validate_timestamps=0 ; ВЫКЛЮЧИ на боевом сервере!validate_timestamps=0 критически важен. Иначе при каждом запросе PHP будет проверять, не изменился ли файл на диске, создавая нагрузку на файловую систему.Итог
PHP-движок обожает порядок. Чем более статичным, типизированным и линейным является твой код, тем легче виртуальной машине превратить его в быстрые нули и единицы. Прежде чем рефакторить цикл, убедись, что у тебя включен OPcache — зачастую этого достаточно, чтобы снять симптомы «медленного сайта».