Piotr Rybałtowski

Programista PHP, Symfony

PHPProgramowanieZend Framework

Skrypty konsolowe w aplikacji ZF2

Zend Framework 2 (od niedawna dostępny w wersji stabilnej) wśród licznych nowości przyniósł jedną, która bardzo mi się podoba i zawsze mi jej brakowało. Chodzi o wbudowaną obsługę skryptów konsolowych. Czyli poleceń w aplikacji, które z poziomu konsoli można wywoływać. Mogą to być akcje odpalane z crona, zarządzanie aplikacją, włączanie trybu maintenance, sprawdzenie stanu system czy cokolwiek jest potrzebne. Całość jest bardzo łatwa do skonfigurowania, a uruchomienie sprowadza się do wykonania przez php głównego skryptu index.php (chociaż ja wolę utworzyć do tego dodatkowy skrypt).

Konfiguracja

Konfiguracja obywa się analogicznie do konfiguracji zwykłych routerów HTTP, czyli zazwyczaj w plikach module.config.php poszczególnych modułów. Jest ona dodatkowo zagnieżdżona na głównym poziomie w kluczu console, a dopiero w nim znajduje się klucz router i routes.

return array(
    'console' => array(
        'router' => array(
            'routes' => array(
                'user-create' => array(
                    'options' => array(
                        'route'    => 'user create [--verbose|-v] <userEmail>',
                        'defaults' => array(
                            'controller' => 'MyApp\Controller\Users',
                            'action'     => 'create',
                        ),
                    ),
                ),
            ),
        ),
    ),
);

Jak widać konfiguracja jest bardzo podobna do standardowych: zawiera ścieżkę routingu i domyślne parametry. Nieco inaczej konfiguruje się właśnie parametry. Nie ma tutaj takiego formatu jak w routerze Segment, czyli :nazwa. Parametry możemy podadać na różne sposoby, a składnia przypomina standardową składnie podawaną w pomocy i dokumentacji wielu poleceń linuksowych. powyższy przykład umożliwia ustawienie dwóch parametrów: verbose (skrótowo v), który jest flagą true/false (podany/niepodany) oraz userEmail, który jest parametrem tekstowym, czyli pod zmienną dostępna będzie zawartość wpisana w poleceniu.

Do dyspozycji mamy kilka rodzajów parametrów:

  • polecenia tekstowe – stałe teksty, które mogą być wpisane albo być nieobowiązkowe oraz mogą posiadać alternatywy, np. user (create|delete) spowoduje, że zarówno polecenie user create jak i user delete będą akceptowane. Polecenia te będą dostępne jako parametry flagowe,
  • flagi – pokazane w przykładzie wyżej, działają podobnie jak polecenia tekstowe ale mają inne formatowanie – myślniki z przodu. Również mogą być obowiązkowe lub nie oraz posiadać alternatywy,
  • parametry z wartością – pokazane na przykładzie userEmail, mogę mieć formę parametru tekstowego lub opcji –nazwa=wartosc,
  • grupy parametrów – specjalny zapis łączący powyższe funkcje i pozwalający na zapisywanie parametrów pod nazwami.

Pełne szczegóły na temat dostępnych formatów wraz z opisem oraz przykładami znajdują się w oficjalnej dokumentacji.

Uruchomienie

Uruchamianie skryptów jest bardzo łatwe. Sprowadza się do wykonania przez konsolowy interpreter php głównego pliku public/index.php. I to wszystko! W moich aplikacjach lubię dla poprawy czytelności dodać skrypt w stylu bin/myapp, który jest po prostu takim uruchomieniem index.php ale można go uruchamiać jako polecenie:

#!/usr/bin/env php
<?php
require __DIR__ . '/../public/index.php';

Dzięki temu polecenia można uruchamiać bardzo łatwo z katalogu głównego aplikacji:

bin/myapp user create --verbose email@example.com

Efekt będzie podobny do tego (kliknij aby powiększyć):

Skrypt konsoli ZF2 - uruchomienie akcji

Informacje dla użytkownika (banner, usage)

Moduły ZF2 mają dwie funkcjonalności ułatwiające użytkownikom tworzonej aplikacji korzystanie z poleceń: banner informacyjny i instrukcje używania.

Banner informacyjny to nic innego jak wiadomość pokazywana w konsoli, gdy użytkownik nie wpisze żadnych poleceń. Moduł, który chce dodać swoją wiadomość powinien implementować interfejs Zend\ModuleManager\Feature\ConsoleBannerProviderInterface, który posiada jedną metodę: getConsoleBanner. Powinna ona zwracać string, który będzie po prostu wypisany w konsoli, np. po utworzeniu metody:

/**
 * @param AdapterInterface $console
 * @return string
 */
public function getConsoleBanner(AdapterInterface $console)
{
    return '*************************************************' . PHP_EOL .
           '*     Witaj w trybie poleceń mojej aplikacji    *' . PHP_EOL .
           '*************************************************' . PHP_EOL;
}

i wpisaniu polecenia otrzymamy efekt podobny do tego (kliknij aby powiększyć):

Skrypt konsoli ZF2 - banner informacyjny

O ile banner wyświtlany jest przy każdym uruchomieniu polecenia w konsoli, o tyle informacje o użyciu pokazywane są tylko, gdy wpisane polecenie nie pasuje do żadnego ze znanych. Służy do poinformowania użytkownika o dostępnych poleceniach, ich formacie oraz pełnionej roli. Aby moduł mógł wyświetlać taką pomoc, musi implementować interfejs Zend\ModuleManager\Feature\ConsoleUsageProviderInterface oraz posiadać metodę getConsoleUsage. Metoda powinna zwracać string (podobnie jak w przypadku banneru) lub array. Ta druga forma daje dużo większe możliwości. Zwracana tablica może być utworzona jako klucz => wartość, gdzie klucz to format polecenia, a wartość to jego opis. Polecenia zostaną przy wyświetlaniu zebrane ze wszystkich modułów oraz odpowiednio sformatowane (szerokości). Podane tutaj polecfenia są tylko informacją dla użytkownika i nie mają wpływu na routing poleceń.

Aby uzyskać pomoc na temat polcenia z przykładu z początku wpisu można utworzyć metodę:

/**
 * @param AdapterInterface $console
 * @return array
 */
public function getConsoleUsage(AdapterInterface $console)
{
    return array(
        'user create [--verbose|-v] <userEmail>' => 'Tworzy konto użytkownika o podanym adresie email',
    );
}

Po wpisaniu polecenia otrzymamy efekt podoby do tego (kliknij aby powiększyć):

Skrypt konsoli ZF2 - dostępne polecenia

Skomentuj lub zadaj pytanie

Witryna wykorzystuje Akismet, aby ograniczyć spam. Dowiedz się więcej jak przetwarzane są dane komentarzy.