Jak jednoduše použít Symfony\Console ve vašich Nette projektech. Jak vytvořit vlastní command, jak ho zaregistrovat a nakonec spustit. S tímhle vším vám pomůže Contributte\Console.
Symfony\Console je v PHP světě poměrně rozšířený a známý nástroj. Napsala se celá řada příkazů pro práci s databází, generování obsahu, nespočet cronu a dalšího. A protože nechcem znovu vynálezat kolo, ukážeme si jak ji jednoduše vložíme do Nette projektu.
Spustit command z příkazové řádky se hodí např. při vývoji, kdy chceme vytvořit nové migrace, vymazat databázi, smazat cache, přidat uživatele apod. Taktéž se hodí při spouštění dlouhotrvajících scriptů, např. při počítání různých statistik, generování PDF. Svoje využití najdou commandy i při cron jobech. Obecně se dá řici, že commandy nám pomáháji ovládat aplikaci přes malé jednoduché příkazy, kterým lze předat nějaké argumenty (arguments), případně doladit přes atributy (options).
console foo:bar <argument> --option <baz> --option2Rád bych vám ukázal tyto 3 způsoby integrace:
- stará dobrá
kdyby/console - čistě přes
symfony/console - integrace přes
contributte/console
Stará dobrá Kdyby\Console
Kdyby\Console je tu s námi už delší dobu, určitě spadá mezi nejpoužívanější balíčky do Nette vůbec. Je to parádní práce z dílny Filipa Procházky
V čem vidím problém, je konkurence a také, že se z Kdyby\Console stal poněkud větší baliček než by mohl být. Když chtěl někdo do teď integrovat symfony/console do Nette, šáhl v 99% po Kdyby balíčku. To znamená, že kdyby to Filip netáhnul dál, postupně by balíček stárnul. To že jsem balíček označil jako větší moloch, není myšleno hanlivě. Díky tomu můžeme dnes pohodlně zavolat php www/index.php a uvidíme nám známou consoli. Kvůli této pohodlnosti, je tam však celkem dost kódu, který považujicí spíše za nadbytečný. Kdyby přetěžuje váš router a vkládá tam routu, která se volá v případě že aplikace beží v CLI modu.
Do nedávna nebyla žádná jiná implementace Symfonydo Nette, což mi škoda. Člověk by měl mít na výběr z více možností, než si napíše vlastní (;-D).
Dnes tu proto máme contributte/console.
Čistá symfony/console integrace
Není nic jednoduššího než bez dalších závislostí přidat symfony console do Nette napřímo.
Nainstalujeme symfony console do našeho projektu.
composer require symfony/consoleDále musíme zaregistrovat Symfony\Component\Console\Application jako službu v našem configu. Můžeme definovat i jméno a verzi, nicméně, není to uplně důležité. V dalším kroku přidáme ukázkový command App\Commands\TestCommand.
services:
console.application:
class: Symfony\Component\Console\Application
setup:
# Configuration =================
- setName('My CLI')
- setVersion('1.0')
# Commands ======================
- add(App\Commands\TestCommand())Poslední částí je spouštěcí script, který vytvoříme do bin/console.
#!/usr/bin/env php
<?php
/** @var Nette\DI\Container $container */
$container = require __DIR__ . '/../app/bootstrap.php';
// Run symfony application.
$app = $container->getByType(Symfony\Component\Console\Application::class);
// Ensure exit codes
exit($app->run());Snadné, rychlé, téměr bez práce. Má to pár nevýhod a to, že commandy nejsou registrované a volané tzn. lazy a také, že každý command musíme ručně přidat do Symfony\Component\Console\Application.
Chtěl jsem skloubit Kdybyspolu s jednoduchým a přímočarým řešením. A tak vznikl balíček contributte.
Integrace pomocí contributte/console
Tento balíček vznikl jako alternativa ke Kdyby, jde ale jiným minimalistickým směrem. Stejně jako Filip, který se věnoval/věnuje údržbe Kdyby několik let, taktěž moje balíčky mají long-term-support.
Pomocí composeru nainstalujeme balíček.
composer require contributte/consoleRegistrace do Nette aplikace je přes CompilerExtension.
extensions:
console: Contributte\Console\DI\ConsoleExtensionKonfigurovat lze všemožné parametry a to např.
console:
name: Acme Project
version: 1.0
catchExceptions: true / false
autoExit: true / false
url: https://contributte.com
helperSet: @customHelperSet
helpers:
- App\Console\MyHelperPro přidání vlastní commandu stačí vytvořit novou třídu s předkem Contributte\Console\Command\AbstractCommand.
A poté zaregistrovat jako službu.
services:
- App\Console\FooCommandHlavní rozdíl oproti Kdybyje, že tento balíček nemodifikuje router, takže vám zavolání php www/index.php nespustí console.
Je nutné proto vytvořit entrypoint do bin/console.
#!/usr/bin/env php
<?php
/** @var Nette\DI\Container $container */
$container = require __DIR__ . '/../app/bootstrap.php';
// Get application from DI container.
$application = $container->getByType(Contributte\Console\Application::class);
// Run application.
exit($application->run());A také mu nastavit práva na spouštění, chmod +x bin/console. Vyvolat consoli je už snadné.
bin/consoleHooray! :+1:
Budu rád pokud vyzkoušíte contributte/console nebo nějaký jiný balíček z rodiny Contributte, třeba contributte/event-dispatcher pro snadnou integraci Symfony/Events.