Як зробити команди лінивого завантаження
Дата оновлення перекладу 2022-11-19
Як зробити команди лінивого завантаження
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)
.