Back-End

31 out, 2013

Console Applications em PHP usando o Symfony/Console

Publicidade

Para cada artigo, teremos uma trilha sonora, uma musica de inspiração. A musica deste artigo é: Break open the Sky – Tony Mac.

Introdução

Neste artigo, vamos estudar como criar uma aplicação PHP que funciona pelo console/prompt de comando. Para isso, vamos utilizar o componente Console, do framework Symfony.

Você já usou o PHPUnit? Não? Então comece a usá-lo a partir de agora! É legal como ele funciona, você executa um app que foi escrito em PHP pelo terminal, mas existe uma diferença – o PHPUnit é um arquivo .phar, e o nosso objetivo é executar através de um arquivo php mesmo. Exemplo: php MeuArquivo.php comando1 –argumento1 –argumento2.

Legal, mas por onde eu começo?

Vamos começar pelo começo, oras (rs)! Primeiro, iremos preparar o nosso ambiente, declarando as nossas dependências. Para isso, vou utilizar o composer. (Não sabe o que é ou não usa? Você não sabe o que está perdendo!). Este é o nosso composer.json.

{
    "require":{
        "symfony/console":"2.3.x"
    }
}

Depois disso, basta rodar o composer install e abracadabra! Tudo que precisamos está lá!

O esqueleto – não, não é o humano e muito menos o do He-man (entenda)!

Por esqueleto entende-se:

Arquivos, requerimentos e configurações básicas que são exigidos para o funcionamento de uma determinada coisa para atingir um objetivo específico.

Nossa, falei bonito! (rs)

Quando rodamos o composer install, já foi criada a nossa pasta vendor, e gerado um autoload. Agora, só precisamos do nosso arquivo principal, o qual iremos chamar de app.php.

$loader = include __DIR__.'/vendor/autoload.php';
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

$app = new Application;
$app->run();

Já temos o básico; para ver o funcionamento, basta rodar no terminal “php app.php”, o retorno tem de ser este: (link da imagem).

A mágica – registrando um comando

Agora vamos registrar um comando, usando o $app->register. Nele, colocaremos os argumentos necessários, se eles são obrigatórios ou opcionais, a resposta, a descrição do comando, a informação que será mostrada no help etc.

$app
    ->register('hello')
    ->setDefinition(array(
        new InputArgument('nome',InputArgument::REQUIRED,'Nome de usuário.')
    ))
    ->setDescription('Função que mostra um Hello Wordl para um usuário.')
    ->setHelp('
        O comando <info>hello</info> exige o argumento <info>nome</info>.
        Exemplos:
        <comment>php app.php hello Lukas</comment>
    ')
    ->setCode(function (InputInterface $input, OutputInterface $output){
        $nome = $input->getArgument('nome');
        $output->writeln('Hello '.$nome.'.');
    });

Observe que, após registrarmos o comando “hello”, usamos o $app->setDefinition. Ele é um array de todos os argumentos do comando registrado anteriormente.

->setDefinition(array(
        new InputArgument('nome',InputArgument::REQUIRED,'Nome de usuário.')
))

Para cada argumento, é necessário instanciar o objeto InputArgument. Se quiséssemos um argumento chamado “sobrenome”, ficaria:

->setDefinition(array(
        new InputArgument('nome',InputArgument::REQUIRED,'Nome de usuário.'),
        new InputArgument('sobrenome'InputArgument::OPTIONAL, 'Sobrenome do usuário.')
))

No $app->setHelp, definimos a mensagem que irá aparecer e no $app->setCode e todas as rotinas/algoritmos/tarefas etc. que aquele determinado comando realiza. Observem que eu tive de pegar o argumento “nome” através do $input->getArgument (se tivesse usado o argumento sobrenome, teria de fazer o mesmo); para exibir a mensagem, usei o $output->writeln (sim, aquele mesmo do pascal, rs).

        ->setCode(function (InputInterface $input, OutputInterface $output){
        $nome = $input->getArgument('nome');
        $output->writeln('Hello '.$nome.'.');
})

Open your mind!

Abra a sua mente… as possibilidades são inúmeras! Exemplo? PHPUnit, Composer… todos eles são escritos em PHP, mas são compactados em .phar, o que te impede de fazer isso?

Legal, Lukas, você falou, falou, falou mas não mostrou o resultado final. Penso eu que a curiosidade é um dos requerimentos básicos para ser um bom desenvolvedor. Então, irei deixar isso por conta de vocês! Testem os comandos “php app.php hello Nome” e “php app.php help hello”.

Considerações Finais

A documentação do Symfony\Console, você pode encontrar aqui.
Você pode encontrar o código completo neste repositório no Github.
O código foi escrito usando o Vim, experimente-o, vale a pena!
Dúvidas? Só comentar que eu as respondo – nos comentários, ou através de G+ e Twitter.