PHP Reflection и SPL
Reflection API
PHP Reflection API позволяет анализировать классы, интерфейсы, функции, методы и расширения. По сути, это «обратная разработка» кода изнут ри PHP. Широко используется в контейнерах внедрения зависимостей, ORM (например, Doctrine) и тестовых фреймворках для изучения классов и их свойств без ручной конфигурации.
Основные классы Reflection
ReflectionClass: информация о классе.ReflectionMethod: информация о методе класса.ReflectionProperty: информация о свойстве класса.ReflectionFunction: информация о функции.ReflectionParameter: информация о параметре функции/метода.
Пример: получение приватных свойств
class User {
private string $name = "John Doe";
}
$reflector = new ReflectionClass('User');
$property = $reflector->getProperty('name');
$property->setAccessible(true); // Начиная с PHP 8.1, свойства автоматически доступны через Reflection
$user = new User();
echo $property->getValue($user); // John Doe
Стандартная библиотека PHP (SPL)
SPL — это набор интерфейсов и классов, предназначенных для решения распространённых задач. Она предоставляет стандартный способ реализации типовых паттернов: итераторов, структур данных и наблюдателей.
Основные компоненты SPL
- Итераторы: классы для итерации по объектам, директориям, файлам и сложным структурам.
ArrayIterator,DirectoryIterator,FilterIterator,RecursiveIteratorIterator.
- Структуры данных: оптимизированные классы для специфического хранения данных.
SplStack,SplQueue,SplHeap,SplPriorityQueue,SplFixedArray(быстрее обычных массивов для больших наборов данных),SplObjectStorage(маппинг для объектов).
- Исключения: стандартные классы исключений —
LogicException,RuntimeException,InvalidArgumentException. - Интерфейсы:
Countable(позволяет использоватьcount()),Serializable,SplObserver,SplSubject.
Различие между SplFixedArray и Array
Стандартный PHP array на самом деле является упорядоченной картой (хеш-таблицей). SplFixedArray — это настоящий C-подобный массив с фиксированным размером и целочисленными индексами, что делает его быстрее и эффективнее по памяти для больших наборов данных с числовыми индексами.
PHP как демон (Swoole, RoadRunner)
Современный PHP больше не ограничен жизненным циклом «запрос-ответ» (когда скрипт создаётся и уничтожается при каждом запросе). С помощью таких инструментов, как Swoole, RoadRunner или Workerman, PHP может работать как долгоживущий процесс (демон).
Преимущества
- Производительность: инициализация (загрузка фреймворка, конфигурации, DIC) происходит один раз при запуске, а не при каждом запросе.
- Сохранение состояния: подключения к БД, кэши и объекты могут оставаться в памяти между запросами.
- Асинхронные задачи: встроенная поддержка неблокирующего ввода-вывода, таймеров и фоновых задач.
Риски и сложности
- Утечки памяти: поскольку процесс не завершается, любая некорректно очищенная память (например, статические переменные, глобальные массивы) будет накапливаться, что в конечном итоге приведёт к падению процесса.
- Глобальное состояние: глобальные переменные или статические свойства переносятся между запросами, что может привести к «загрязнению состояния» (данные пользователя A отображаются пользователю B).
- Зависшие ресурсы: открытые файловые дескрипторы или подключения к БД могут оставаться открытыми слишком долго или зависать, если управление ими организовано некорректно.
- Обработка ошибок: фатальная ошибк а может уронить весь серверный воркер, а не только один запрос.
- Обновление кода: изменения в коде требуют полного перезапуска демона для вступления в силу (по умолчанию «горячая перезагрузка» отсутствует).
Постоянные подключения к базе данных
PHP предоставляет механизм постоянных подключений к БД (например, PDO::ATTR_PERSISTENT => true).
Плюсы
- Снижает накладные расходы на установку нового TCP-соединения и рукопожатие при каждом запросе.
- Повышает производительность в условиях высокой конкурентности.
Минусы
- Исчерпание соединений: поскольку соединения не закрываются по завершении скрипта, они остаются в пуле. При некорректном управлении можно превысить лимит
max_connectionsбазы данных. - Устаревшее состояние: временные таблицы, сессионные переменные или состояния транзакций могут перейти к следующему запросу, использующему то же соединение.
- Deadlock'и: длительные транзакции на постоянных соединениях могут вызвать проблемы, если не закрыть их корректно.