O PHP é frequentemente associado ao desenvolvimento web, mas sua versatilidade vai muito além: ele é uma excelente escolha para criar ferramentas de linha de comando (CLI). Nesta aula, vamos explorar como o PHP pode ser usado para construir scripts executáveis no terminal, desde os mais simples até aplicações mais complexas com o Symfony Console. Você verá como o PHP se comporta no ambiente CLI, como manipular argumentos e como estruturar comandos de forma profissional.

Dominar a linha de comando com PHP é uma habilidade valiosa para automatizar tarefas, processar dados, criar ferramentas de manutenção e muito mais. Vamos começar com os fundamentos e evoluir para técnicas avançadas.

Scripts CLI

Um script CLI em PHP é um arquivo que pode ser executado diretamente no terminal, sem a necessidade de um servidor web. Para isso, o PHP deve estar instalado e acessível como executável. A sintaxe básica é a mesma do PHP para web, mas com algumas diferenças importantes: não há superglobals como $_GET ou $_POST; em vez disso, temos acesso a constantes e funções específicas do SAPI (Server API) de linha de comando.

O primeiro passo é criar um arquivo PHP e executá-lo com o comando php arquivo.php. Dentro do script, podemos usar echo, print ou fwrite(STDOUT, ...) para saída, e fgets(STDIN) ou readline() para entrada do usuário. Vamos ver um exemplo simples:

<?php
// saudacao.php
echo "Olá, mundo!\n";
?>

Para executar: php saudacao.php. A saída será Olá, mundo!. Note que usamos \n para quebrar linha, pois no terminal não há tags HTML. Também podemos omitir a tag de fechamento ?> em scripts puros para evitar problemas com espaços em branco indesejados.

Outra característica importante: no CLI, o PHP não tem limite de tempo de execução (a menos que configurado) e não há buffer de saída. Isso é útil para scripts longos. Além disso, a constante PHP_SAPI retorna "cli", o que permite verificar se o script está rodando no terminal.

argv

Quando você executa um script PHP no terminal, pode passar argumentos. Eles ficam disponíveis na variável global argv (um array) e na variável argc (o número de argumentos). O primeiro elemento (argv[0]) é sempre o nome do script. Os demais são os argumentos fornecidos.

Vamos criar um script que recebe um nome e uma idade:

<?php
// info.php
if ($argc < 2) {
    echo "Uso: php info.php [nome] [idade]\n";
    exit(1);
}

$nome = $argv[1];
$idade = $argv[2] ?? 'desconhecida';

echo "Nome: $nome, Idade: $idade\n";
?>

Execução: php info.php Maria 30. A saída será Nome: Maria, Idade: 30. Note que usamos $argv[2] ?? 'desconhecida' para fornecer um valor padrão caso o argumento não seja passado. Também é possível usar array_slice para ignorar o nome do script e obter apenas os argumentos do usuário.

Uma prática comum é usar a função getopt() para lidar com opções como -n ou --nome. Isso torna os scripts mais flexíveis. Por exemplo:

<?php
// opcoes.php
$opcoes = getopt('n:a:', ['nome:', 'idade:']);

$nome = $opcoes['n'] ?? $opcoes['nome'] ?? 'desconhecido';
$idade = $opcoes['a'] ?? $opcoes['idade'] ?? 'desconhecida';

echo "Nome: $nome, Idade: $idade\n";
?>

Execução: php opcoes.php -n Maria -a 30. Isso permite que o usuário passe os argumentos de forma mais legível.

Symfony Console (visão geral)

O Symfony Console é um componente robusto para criar aplicações de linha de comando em PHP. Ele oferece uma estrutura organizada, com classes para comandos, entrada/saída, formatação de texto e muito mais. É amplamente utilizado em frameworks como Laravel (Artisan) e Symfony.

Para começar, você precisa instalar o componente via Composer: composer require symfony/console. Em seguida, você cria uma classe de comando que estende Symfony\Component\Console\Command\Command e define um nome, uma descrição e o método execute(). Vamos ver um exemplo:

<?php
// src/Command/SaudacaoCommand.php
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 SaudacaoCommand extends Command
{
    protected static $defaultName = 'saudacao';

    protected function configure()
    {
        $this
            ->setDescription('Exibe uma saudação personalizada.')
            ->addArgument('nome', InputArgument::REQUIRED, 'Seu nome.')
            ->addOption('grito', null, InputOption::VALUE_NONE, 'Exibe em maiúsculas.');
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $nome = $input->getArgument('nome');
        $mensagem = "Olá, $nome!";

        if ($input->getOption('grito')) {
            $mensagem = strtoupper($mensagem);
        }

        $output->writeln($mensagem);
        return Command::SUCCESS;
    }
}
?>

Depois, você cria um aplicativo e registra o comando:

<?php
// bin/console
require __DIR__ . '/vendor/autoload.php';

use Symfony\Component\Console\Application;

$app = new Application();
$app->add(new SaudacaoCommand());
$app->run();
?>

Executando php bin/console saudacao Maria --grito teremos OLÁ, MARIA!. O Symfony Console cuida da validação de argumentos, formatação de saída, tabelas, barras de progresso e muito mais.

O componente também permite criar comandos com interatividade (perguntas ao usuário), saída colorida e testes automatizados. É uma escolha profissional para projetos que exigem ferramentas CLI complexas.

Casos de uso

O PHP na linha de comando é extremamente útil em diversas situações. Um dos casos mais comuns é a automação de tarefas de manutenção, como limpar caches, executar migrações de banco de dados ou gerar relatórios. Muitos frameworks já utilizam comandos CLI para essas tarefas, e você pode criar os seus próprios.

Outro caso é a integração com serviços externos: você pode escrever scripts que consomem APIs, processam filas de mensagens ou sincronizam dados. Por exemplo, um script que busca dados de uma API e os envia para um banco de dados pode ser executado periodicamente via cron.

Também é possível usar PHP CLI para processamento de arquivos, como converter formatos, analisar logs ou gerar arquivos de configuração. A capacidade de combinar com expressões regulares e funções de string torna o PHP poderoso para essas tarefas.

Além disso, muitas ferramentas de desenvolvimento são construídas com PHP CLI, como o Composer (gerenciador de dependências) e o PHPUnit (testes). Entender como criar comandos CLI é essencial para contribuir com esses projetos ou criar suas próprias ferramentas.

Boas práticas e observações finais

Ao desenvolver scripts CLI em PHP, é importante seguir algumas boas práticas: sempre valide os argumentos e forneça mensagens de erro claras; use códigos de saída diferentes para sucesso (0) e falha (1); documente o uso do script no próprio código ou em um README; e considere usar bibliotecas como Symfony Console para projetos maiores.

Outra dica: no CLI, você pode usar a função error_log() para registrar erros em arquivos, e a função set_time_limit(0) para permitir execução longa. Lembre-se também de que o PHP CLI tem configurações próprias no php.ini, como memory_limit e max_execution_time, que podem ser ajustadas.

Finalmente, teste seus scripts em diferentes ambientes (Linux, Windows) para garantir portabilidade. O PHP CLI é uma ferramenta poderosa e versátil que merece um lugar no seu arsenal de desenvolvimento.

Referências

Exercícios

  1. Crie um script PHP que aceite um número como argumento e imprima se ele é par ou ímpar. Use argv e valide a entrada.

    ✓ Resposta:
    <?php
    if ($argc != 2) {
        echo "Uso: php par_impar.php [numero]\n";
        exit(1);
    }
    
    $numero = (int)$argv[1];
    if ($numero % 2 == 0) {
        echo "$numero é par\n";
    } else {
        echo "$numero é ímpar\n";
    }
    ?>
    
  2. Escreva um script que receba uma lista de nomes como argumentos e exiba cada um em uma linha, ordenados alfabeticamente.

    ✓ Resposta:
    <?php
    if ($argc < 2) {
        echo "Uso: php nomes.php [nome1] [nome2] ...\n";
        exit(1);
    }
    
    $nomes = array_slice($argv, 1);
    sort($nomes);
    foreach ($nomes as $nome) {
        echo $nome . "\n";
    }
    ?>
    
  3. Usando getopt(), crie um script que aceite as opções -n (nome) e -i (idade) e exiba uma mensagem como "Nome: X, Idade: Y".

    ✓ Resposta:
    <?php
    $opcoes = getopt('n:i:');
    
    $nome = $opcoes['n'] ?? 'desconhecido';
    $idade = $opcoes['i'] ?? 'desconhecida';
    
    echo "Nome: $nome, Idade: $idade\n";
    ?>
    
  4. Instale o Symfony Console via Composer e crie um comando chamado saudacao que aceite um argumento nome e uma opção --grito para imprimir em maiúsculas. Execute-o no terminal.

    ✓ Resposta:

    Primeiro, crie um projeto com composer init e instale o componente: composer require symfony/console. Depois, crie a classe do comando e o aplicativo como mostrado na aula. Exemplo de execução: php bin/console saudacao Maria --grito.

  5. Descreva um caso de uso real para um script PHP CLI e explique como você o estruturaria (quais argumentos, opções, e como lidaria com erros).

    ✓ Resposta:

    Um exemplo é um script para backup de banco de dados. Ele poderia aceitar opções como --host, --user, --pass, --db e --output. O script conectaria ao banco, executaria um dump e salvaria em um arquivo. Para erros, usaria códigos de saída diferentes: 0 para sucesso, 1 para falha de conexão, 2 para falha de escrita. Também poderia usar try-catch para exceções e registrar logs.