Как сделать команды ленивой загрузки¶
Note
Если вы используете полностековый фреймворк Symfony, то вы скорее всего ищете подробности о создании команд ленивой загрузки
Традиционный способ добавления команд в ваше приложение - это использование
add()
, который ожидает
экземпляр Command
в качестве аргумента.
Для того, чтобы лениво загружать команды, вам нужно зарегистрировать срединный
загрузчик, который будет отвечать за возвращение экземпляров Command
:
1 2 3 4 5 6 7 8 9 10 11 | use App\Command\HeavyCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\CommandLoader\FactoryCommandLoader;
$commandLoader = new FactoryCommandLoader(array(
'app:heavy' => function () { return new HeavyCommand() },
));
$application = new Application();
$application->setCommandLoader($commandLoader);
$application->run();
|
Таким образом, экземпляр HeavyCommand
будет создан только тогда, когда
команда app:heavy
будет действительно вызвана.
Этот пример использует встроенный класс
FactoryCommandLoader
, но
метод setCommandLoader()
принимает любой экземпляр
CommandLoaderInterface
,
так что вы можете использовать собственные реализации.
Встроенные загрузчики команд¶
FactoryCommandLoader
¶
Класс FactoryCommandLoader
предоставляет простой способ получения команд ленивой загрузки, так как он берёт
массив фабрик Command
в качестве единственного аргумента конструктора:
1 2 3 4 5 6 | use Symfony\Component\Console\CommandLoader\FactoryCommandLoader;
$commandLoader = new FactoryCommandLoader(array(
'app:foo' => function () { return new FooCommand() },
'app:bar' => array(BarCommand::class, 'create'),
));
|
Фабрики могут быть любым PHP вызываемым и будут выполнены каждый раз,
когда вызывается get()
.
ContainerCommandLoader
¶
Класс ContainerCommandLoader
может быть использован для загрузки команды из контейнера PSR-11. Таким образом,
её конструктор берёт реализацию PSR-11 ContainerInterface
в качестве своего
первого аргумента, а карту команды - в качестве последнего. Карта команды должна
быть массивом с именами команд в качестве ключей и идентификаторами сервисов в
качестве значений:
1 2 3 4 5 6 7 8 9 10 | use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
use Symfony\Component\DependencyInjection\ContainerBuilder;
$container = new ContainerBuilder();
$container->register(FooCommand::class, FooCommand::class);
$container->compile();
$commandLoader = new ContainerCommandLoader($container, array(
'app:foo' => FooCommand::class,
));
|
Таким образом, выполнение команды app:foo
загрузит сервис FooCommand
,
вызвав $container->get(FooCommand::class)
.
Эта документация является переводом официальной документации Symfony и предоставляется по свободной лицензии CC BY-SA 3.0.