-
-
Notifications
You must be signed in to change notification settings - Fork 1
Class scanning
github-actions[bot] edited this page Jun 25, 2026
·
1 revision
Метод Container::scan() находит PHP-классы в каталоге и регистрирует их для autowiring через autowire().
$container = new Container();
$container->enableAutowiring(); // необязательно, если только autowire() по scan
$container->scan(__DIR__ . '/src/Services', 'App\\Services\\');
$service = $container->get(App\Services\OrderService::class);Второй аргумент — фильтр по префиксу namespace. Только классы, чьё FQCN начинается с App\Services\, будут зарегистрированы.
Без фильтра:
$container->scan(__DIR__ . '/src');Класс CloudCastle\DI\ClassScanner:
- Рекурсивно обходит каталог (
RecursiveDirectoryIterator). - Берёт только файлы с расширением
.php. - Читает содержимое файла без выполнения (
file_get_contents). - Извлекает
namespaceи имяclassрегулярными выражениями. - Проверяет через
class_exists()(срабатывает autoload). - Оставляет только instantiable классы (не abstract, не interface, не trait).
Поддерживаются модификаторы abstract, final, readonly в объявлении класса в regex.
foreach ($scanner->scan($directory, $namespace) as $className) {
if (!$this->hasDefinition($className)) {
$this->autowire($className);
}
}| Ситуация | Результат |
|---|---|
Класс уже зарегистрирован через set()
|
пропуск — явная регистрация сохраняется |
Класс уже в autowire()
|
autowire() вызывается снова (сброс кэша singleton) |
| Файл без класса / только trait / interface | пропуск |
| Класс abstract | пропуск |
| Namespace не совпадает с фильтром | пропуск |
| Каталог не существует | ContainerException |
-
PSR-4 autoload должен быть настроен: после парсинга имени класса вызывается
class_exists(). - Один класс на файл — стандартная практика PSR-4; иначе autoload может не найти класс.
- Файлы с синтаксическими ошибками могут не загрузиться — класс будет пропущен.
Префикс нормализуется: trailing \ добавляется автоматически.
$container->scan($dir, 'App\\Services'); // эквивалентно 'App\\Services\\'
$container->scan($dir, 'App\\Services\\');Класс App\Services\OrderHandler — включён.
Класс App\Domain\Order — исключён.
scan() — runtime-регистрация в контейнере, не замена Composer autoload. Он не индексирует vendor и не компилирует контейнер.
Типичный сценарий — bootstrap приложения:
function bootstrapContainer(): Container
{
$container = new Container();
$container->enableAutowiring();
$container->scan(__DIR__ . '/../src/Application', 'App\\Application\\');
// Явные переопределения поверх scan
$container->set(LoggerInterface::class, new MonologLogger(...));
return $container;
}- Не находит enum (regex ищет
class, неenum). - Не парсит несколько классов в одном файле.
- Не выполняет static side effects при сканировании — но
class_exists()загружает класс через autoload. - Anonymous classes и файлы только с
return/ функциями — пропуск.
- Autowiring — разрешение зависимостей после scan
-
Справочник API —
scan(),ClassScanner