
20 Maj Symfony Command – stwórz własną komendę konsolową
Nie raz w aplikacjach potrzebujemy, aby pewne procesy wywoływały się regularnie. W Cross Skills wydarzenia po dacie ich zakończenia powinny zmieniać status na zakończone. Jak to zrobić? Naturalnie do głowy przychodzi cron i bardzo dobrze. Jednak coś w tym cronie trzeba wywołać. Jak to zrobić dla aplikacji w Symfony? Bardzo prosto, wystarczy zdefiniować komendę konsolową czyli symfony command, która uruchomi odpowiedni proces.
Konfiguracja Symfony Command
use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; class OverdueEventsCommand extends Command { protected function configure() { $this ->setName('event:overdue') ->setDescription('Change status overdue events.') ->addArgument( 'date', InputArgument::OPTIONAL, 'Change status only for events for the day 2017-05-20 bin/console event:overdue 2017-05-20"' ); } /** * @param InputInterface $input * @param OutputInterface $output */ protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln('Start.....'); //... $output->writeln('.....End'); } }
Tak oto wygląda komenda. Dziedziczy z klasy Command zawartej w Console Component. Możesz go zainstalować composerem: symfony/console. Aby skonfigurować sposób wywołania komendy musimy stworzyć funkcję configure(), w której jak w powyższym przykładzie, określamy samą komendę, ustawiamy opis podpowiadający użytkownikom, co dana komenda robi. Parametry opcjonalne i wymagane również określamy w tym miejscu, wyżej jest przykład parametru opcjonalnego, jeśli chcemy ustawić parametr wymagany, wystarczy, że zamiast InputArgument::OPTIONAL podamy InputArgument::REQUIRED. Druga funkcja to execute() przyjmująca parametry wejścia i wyjścia. Jak łatwo się domyślić to tutaj znajdziemy ciało komendy, czyli kompletny proces.
Jak użyć kontenera?
Jeśli chcemy w komendzie wywołać serwis, musimy lekko zmodyfikować powyższy kod.
namespace EventBundle\Command; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; class OverdueEventsCommand extends ContainerAwareCommand { protected function configure() { $this ->setName('event:overdue') ->setDescription('Change status overdue events.') ->addArgument( 'date', InputArgument::OPTIONAL, 'Change status only for events for the day 2017-05-20 bin/console event:overdue 2017-05-20"' ) ->addOption( 'current_month', null, InputOption::VALUE_REQUIRED, 'Process events only from this month example: --current-month"' ); } /** * @param InputInterface $input * @param OutputInterface $output */ protected function execute(InputInterface $input, OutputInterface $output) { $output->writeln('Start.....'); $date = $input->getArgument('date'); $this->getContainer()->get('event.overdue_process')->process($date); $output->writeln('.....End'); } }
Pojawiły się tutaj dwie rzeczy. Pierwsza jest taka, że zamiast dziedziczyć z klasy Command, dziedziczy z klasy ContainerAwareCommand. Dzięki tej zmianie możemy korzystać z kontenera, jak jest to zaprezentowane w funkcji execute. Dodatkowo pokazałam jak zmodyfikować komendę, dodając opcję zamiast parametru. Pobranie informacji czy komenda została wykonana z opcją działa tak samo, jak pobrania argumentu. Na inpucie wystarczy wywołać funkcję getOption(‘nazwa_opcji’). Jak widać, output jest wykorzystywany do wyświetlaniu w konsoli informacji z samego procesu. Tak wykonana funkcja może zostać zarówno wykonana przez Ciebie w konsoli np. bin/console event:overdue, jak i w cronie.
Mam nadzieję, że już wiesz jak stworzyć i wywołać np. w cronie swoją własną komendę. Jeśli masz jeszcze jakieś pytania to śmiało zadaj je w komentarzu.