A partir versão 4.3.0, o PHP suporta um novo tipo
SAPI (Server Application Programming Interface)
chamado CLI que significa Command Line
Interface. Como o próprio nome indica, essa SAPI
tem foco no desenvolvimento de aplicações shell (ou no terminal/linha de comando) com
o PHP. Há algumas diferenças entre a
a CLI SAPI e outras SAPIs que são
explicadas neste capítulo. Mas é errado dizer que
a versão CLI e CGI são SAPIs
diferentes pelo motivo que elas compartilham muitos comportamentos idênticos.
A CLI SAPI foi liberada primeiramente com o
PHP 4.2.0, mas ainda em estágio experimental, sendo necessário
ativá-la explicitamente com a opção --enable-cli durante o
./configure. Desde o PHP 4.3.0 a
CLI SAPI não mais é experimental e a opção
--enable-cli está ligada por default. você pode usar a opção
--disable-cli para desativá-la.
Desde o PHP 4.3.0, o nome, localização e existência dos executáveis CLI e CGI
podem mudar dependendo de como o PHP foi instalado no seu sistema. Por padrão,
quando executado o make, ambos CGI e CLI são compilados e
colocados em sapi/cgi/php e sapi/cli/php,
respectivamente, no seu diretório de fontes PHP. Note que que ambas tem
o nome php. O que acontece durante o make
install depende dos parâmetros do
configure. Se o módulo SAPI é escolhido durante o configure, como o apxs, ou a opção
--disable-cgi é utilizada, a versão CLI é copiada para
{PREFIX}/bin/php durante o make install
em vez da versão CGI ser colocada aqui. Então, por exemplo, se você tiver --with--apxs
na sua linha de configuração, então a versão CLI é copiada para
{PREFIX}/bin/php durante o make
install. Se você quiser sobrescrever a instalação do executável CGI,
use make install-cli depois do make
install. Alternativamente, você pode especificar --disable-cgi
em seu configure.
Nota:
Por serem ambos --enable-cli e
--enable-cgi ligados por padrão, ter um
--enable-cli em seu configure
não necessariamente significa que a versão CLI será copiada para
{PREFIX}/bin/php durante o make install.
Os pacotes para Windows distribuidos entre o PHP 4.2.0 e PHP 4.2.3 forneciam a versão CLI
com o nome php-cli.exe, na mesma pasta que a versão CGI
php.exe. A partir do PHP 4.3.0, os pacotes Windows
distribuem a versão CLI como php.exe em uma pasta separada,
chamada cli ou seja: cli/php.exe.
A partir do PHP 5, a versão CLI também é distribuída no diretório principal, com o nome
php.exe. A versão CGI é distribuída com o nome
php-cgi.exe.
A partir do PHP 5, um novo arquivo php-win.exe começou a ser distribuído.
Esta versão é igual a versão CLI, exceto que esse php-win não exibe nenhum
output e também não disponibiliza nenhum console (nenhuma caixa de texto aparece na tela). Este
comportamento é semelhante ao do php-gtk. Você pode configurar esse modo com
--enable-cli-win32.
Que versão de SAPI eu tenho?:
Na linha de comando, digitando php -v, ele lhe dirá
se o php é CGI ou CLI. Veja também a função
php_sapi_name() e a constante
PHP_SAPI.
Nota:
Um manual Unix man foi acrescentado no PHP 4.3.2. Você pode
vê-lo digitando man php em seu ambiente shell.
Diferenças importantes das CLI SAPI comparada com outras
SAPIs:
Diferentemente da CGI SAPI, nenhum header é impresso
na saída.
A CGI SAPI possui um meio de suprimir os headers
HTTP, mas não há uma chave equivalente para ativá-los na CLI
SAPI.
A versão CLI é definida silenciosa por padrão. Mas as chaves -q
e --no-header são mantidas para compatibilidade, de forma que você possa utilizar scripts CGI antigos.
Ela não altera o diretório de execução para o do script.
(as chaves -C e --no-chdir também são mantidas para compatibilidade).
Mensagens de erro em texto simples (sem formatação HTML).
Estas são as diretivas do php.ini que são sobrescritas pela CLI
SAPI porque não fazem sentido no ambiente shell:
Tabela 23-1. Diretivas php.ini sobrescritas
| Diretiva | Valor default CLI SAPI | Comentários |
|---|
| html_errors | FALSE |
Pode ser bem difícil de ler mensagens de erro no seu shell quando
elas estão embebidas dentro de tags HTML,
por isso essa diretiva tem default para FALSE.
|
| implicit_flush | TRUE |
Essa diretiva causa que qualquer saída gerada de um
print(), echo() e semelhantes sejam
imediatamente escritas para o output e não cacheadas em nenhum buffer. Você
ainda pode usar o output buffering
se você precisa atrasar ou manipular a saída padrão.
|
| max_execution_time | 0 (unlimited) |
Devido as infinitas possibilidades da utilização do PHP em
ambientes shell, o tempo máximo de execução foi configurado para
ilimitado. Enquanto aplicações escritas para web são geralmente executadas
em poucos segundos, aplicações no shell tendem a ter um tempo de execução
mais longo.
|
| register_argc_argv | TRUE |
Como essa diretiva é TRUE você sempre terá acesso as variáveis
argc (número de argumentos passados para a
aplicação) e argv (array dos argumentos
informados) na CLI SAPI.
A partir do PHP 4.3.0, as variáveis do PHP $argc
e $argv são registradas e preenchidas com os valores
apropriados quando utilizando a CLI SAPI. Antes dessa versão,
a criação dessas variáveis era controlada da mesma forma que as versões
CGI e MODULE
e precisava da diretiva PHP
register_globals configurada
para on. Independentemente da versão ou da configuração
de register_globals, você sempre poderá acessar esses dados através de
$_SERVER ou
$HTTP_SERVER_VARS. Exemplo:
$_SERVER['argv']
|
Nota:
Estas diretivas não podem ser inicializadas com outros valores do
arquivo de configuração php.ini ou um arquivo personalizado (se informado). Esta
limitação existe porque estes valores são aplicados depois que todos
os arquivos de configuração são analisados. Entretanto, seus valores podem ser modificados
durante a execução (o que pode não fazer sentido para todas elas,
por exemplo, register_argc_argv).
Para facilicar a operação no ambiente shell, as seguintes constantes
estão definidas:
Tabela 23-2. Constantes específicas CLI
| Constante | Descrição |
|---|
| STDIN |
Um stream já aberto para o stdin. Isto economiza
ter de abrí-lo com
$stdin = fopen('php://stdin', 'r');
|
|
| STDOUT |
Um stream já aberto para o stdout. Isto economiza
ter de abrí-lo com
$stdout = fopen('php://stdout', 'w');
|
|
| STDERR |
Um stream já aberto para o stderr. Isto economiza
ter de abrí-lo com
$stderr = fopen('php://stderr', 'w');
|
|
Considerando isso, você não precisará mais abrí-los, por exemplo o
stderr você mesmo, mas simplesmente usar a constante em vez
do recurso stream:
php -r 'fwrite(STDERR, "stderr\n");'
|
Você não precisa fechar explicitamente esses streams. Isto é realizado automaticamente
pelo PHP.
A CLI SAPI não modifica o diretório de execução atual para o diretório
onde o script é interpretado!
Exemplo mostrando a diferença da CGI SAPI:
<?php /* Nossa aplicação de teste chamada test.php */ echo getcwd(), "\n"; ?>
|
Quando utilizando a versão CGI, a saída é:
$ pwd
/tmp
$ php -q outro_diretorio/test.php
/tmp/outro_diretorio |
Isto mostra como o PHP modifica o diretório atual
para aquela onde o script é executado.
Utilizando a versão CLI SAPI:
$ pwd
/tmp
$ php -f outro_diretorio/test.php
/tmp |
E isto mostra a grande flexibilidade ferramentas shell em
PHP.
Nota:
A CGI SAPI suporta o comportamento da CLI SAPI
utilizando a chave -C quando de sua execução na
linha de comando.
A lista de opções de linha de comando fornecidas pelo binário do PHP
pode ser solicitada a qualquer tempo executando o PHP com a
opção -h:
Usage: php [options] [-f] <file> [args...]
php [options] -r <code> [args...]
php [options] [-- args...]
-s Display colour syntax highlighted source.
-w Display source with stripped comments and whitespace.
-f <file> Parse <file>.
-v Version number
-c <path>|<file> Look for php.ini file in this directory
-a Run interactively
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-z <file> Load Zend extension <file>.
-l Syntax check only (lint)
-m Show compiled in modules
-i PHP information
-r <code> Run PHP <code> without using script tags <?..?>
-h This help
args... Arguments passed to script. Use -- args when first argument
starts with - or script is read from stdin |
A CLI SAPI fornecer três maneiras diferentes para você
executar seu código PHP:
Chamando o PHP para executar um arquivo determinado.
php my_script.php
php -f my_script.php |
De ambas maneiras (utilizando ou não a opção -f) o
arquivo my_script.php é executado. Você pode escolher qualquer arquivo para
executar --- seus scripts PHP não precisam terminar com a
extensão .php, podendo ter qualquer nome ou extensão
que você deseje.
Passar o código PHP para execução diretamente a linha
de comando.
php -r 'print_r(get_defined_constants());' |
É preciso ter especial cuidado com a substituição de variáveis shell e
delimitação de strings utilizada.
Nota:
Leia o exemplo cuidadosamente, observando que não há tags de abertura ou fechamento! A
opção -r simplesmente não precisa delas. Utilizando-as você
obterá erros de interpretação.
Fornece código PHP para interpretação via a entrada padrão
(stdin).
Isto mostra a habilidade poderosa de como criar dinamicamente
código PHP e fornecê-lo ao binário, como demonstrado
neste exemplo (apenas demonstrativo):
$ alguma_aplicacao | algum_filtro | php | sort -u >final_output.txt |
Você não pode combinar nenhum das três maneiras para executar código.
Assim como qualquer aplicação shell, não somente o binário do PHP
aceita um certo número de argumentos, mas também seu script PHP
também pode recebê-los. O número de argumentos que podem ser passados para seu script
não é limitado ao PHP (mas o shell tem um certo limite de tamanho
em caracteres que podem ser informados, e não há um padrão para esse
limite). Os argumentos passados para seu script são disponibilizados no array
global $argv. No índice zero sempre conterá o nome do
script (podendo ser - no caso de código PHP
estar vindo da entrada padrão ou da opção de linha de comando
-r). O segunda variável global
$argc contém o número de elementos no
array $argv (mas não o
número de argumentos passados para seu script.
Os argumentos que você deseja passar para seu script não podem começar com o caracter
- e isso não pode ser modificado.
Passando argumentos para seu script que comecem com um
- causará problemas porque o PHP
tentará manuseá-los. Para prevenir isso, utilize o separador de argumentos
--. Depois que esse separador é passado para o
PHP, todos os argumentos restantes são repassados
intocados para seu script.
# Isto não executará o código fornecido e irá fazer o PHP mostrar sua ajuda
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]
# Isto passará o argumento '-h' para seu script e prevenirá o PHP de usá-lo
$ php -r 'var_dump($argv);' -- -h
array(2) {
[0]=>
string(1) "-"
[1]=>
string(2) "-h"
} |
Entretanto, há ainda uma outra maneira de se utilizar o PHP no
shell. Você pode escrever um script que na primeira linha tenha
#!/usr/bin/php e em seguida
código PHP normal, incluindo as tags de
início e fim do PHP. Você também precisa configurar os atributos de
execução do arquivo (por exemplo, chmod +x test) de forma que seu script
seja executado normalmente como um script shell/Perl:
#!/usr/bin/php <?php var_dump($argv); ?>
|
Assumindo que o arquivo foi nomeado como
teste e está no diretório
atual, nós podemos fazer o seguinte:
$ chmod 755 teste
$ ./test -h -- foo
array(4) {
[0]=>
string(6) "./teste"
[1]=>
string(2) "-h"
[2]=>
string(2) "--"
[3]=>
string(3) "foo"
} |
Como você viu, dessa forma não há problemas em passar parâmetros para seu script
que comecem com o caracter
-
Opções com nomes "longos" foram disponibilizados a partir do PHP 4.3.3.
Tabela 23-3. Opções de linha de comando
| Opção | Opção Longa | Descrição |
|---|
| -s | --syntax-highlight |
Mostra o código fonte com destaque de cores.
Esta opção usa o mecanismo interno para interpretar o arquivo e produzir
uma versão HTML do fonte com destaque de cores e a envia para
a saída padrão. Note que ele somente gerará blocos de
<code> [...] </code>,
mas não headers HTML.
Nota:
Esta opção não funciona juntamente com a opção -r.
|
| -s | --syntax-highlighting |
Apelido para --syntax-highlight.
|
| -w | --strip |
Mostra o fonte sem comentários e espaços em branco.
Nota:
Esta opção não funciona juntamente com a opção -r.
|
| -f | --file |
Interpreta e executa o arquivo informado com a opção -f
Esta diretiva é opcional e pode ser deixada de lado. Informar somente
o nome do arquivo para execução é suficiente.
|
| -v | --version |
Imprime as versões o PHP, PHP SAPI e Zend para a saída padrão, por exemplo:
$ php -v
PHP 4.3.0 (cli), Copyright (c) 1997-2002 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2002 Zend Technologies |
|
| -c | --php-ini |
Esta opção informa um diretório onde procurar pelo
php.ini ou especifica um arquivo INI personalizado
diretamente (não presisa ser obrigatoriamente php.ini), por exemplo:
$ php -c /custom/directory/ my_script.php
$ php -c /custom/directory/custom-file.ini my_script.php |
|
| -n | --no-php-ini |
Ignora todo o php.ini. Esta chave está disponível desde o PHP 4.3.0.
|
| -d | --define |
Esta opção permite definir um valor personalizado para qualquer diretiva
de configuração permitida no php.ini. Sintaxe:
Exemplos (linhas cortadas para melhor visualização):
# Omitindo a parte do valor irá configurar a diretiva para "1"
$ php -d max_execution_time
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"
# Passando um valor vazio irá configurar a diretiva para ""
php -d max_execution_time=
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""
# A diretiva de configuração será preenchida com qualquer coisa informada depois do caracter =''
$ php -d max_execution_time=20
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$ php
-d max_execution_time=instonaofazsentido
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "instonaofazsentido" |
|
| -a | --interactive |
Roda o PHP em modo interativo.
|
| -e | --profile-info |
Gera informações estendidas para o debugador/profiler.
|
| -z | --zend-extension |
Carrega a extensão Zend. Se somente o nome de arquivo é fornecido, o PHP tenta carregar
essa extensão do caminho default de bibliotecas do seu sistema
(geralmente especificado em /etc/ld.so.conf em sistemas
Linux). Passando um nome de arquivo com o caminho absoluto irá evitar a
procura no caminho das bibliotecas de sistema. Um nome de arquivo com uma
informação de diretório relativa fará com que o PHP apenas tente
carregar a extensão no caminho relativo ao diretório atual.
|
| -l | --syntax-check |
Esta opção fornece uma maneira conveniente apenas realizar uma checagem de sintaxe
no código PHP fornecido. No sucesso, o texto
No syntax errors detected in <arquivo> é
impresso na saída padrão e informado o código de saida de sistema
0. Em caso de erro, o texto Errors parsing
<filename> juntamente com o a mensagem do interpretador
interno é impressa para a saída padrão e o código de saída de sistema é
255.
Esta opção não procura por erros fatais (como funções não definidas). Use
-f se você deseja detectar erros fatais também.
Nota:
Esta opção não trabalha com a opção -r
|
| -m | --modules |
Utilizando essa opção, o PHP imprime os módulos PHP e Zend compilados
(e carregados):
$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype
[Zend Modules] |
|
| -i | --info |
Esta opção de linha de comando chama a função phpinfo() e imprime
seus resultados. Se o PHP não está funcionando bem, é
interessante fazer um php -i para observar qualquer mensagem
de erro impressa antes ou dentro das tabelas de informação.
Como a saída é em HTML, ela é um
pouco grande.
|
| -r | --run |
Esta opção permite a execução de código PHP direto da
linha de comando. As tags de início e fim do PHP
(<?php e ?>)
não são necessárias e causarão erros
de interpretação se informadas.
Nota:
Cuidados deverão ser tomados utilizando dessa forma para
evitar que haja substituição de variáveis pelo
shell.
Exemplo mostrando um erro de interpretação
$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse error, unexpected '=' |
O problema aqui decorre do sh/bash realizar substituições de variáveis
sempre quando se utilizam aspas ("). Desde que a
variável $foo não deve estar definida, ela é
substituída por nada o que faz que o código passado para o
PHP para execução seja:
$ php -r " = get_defined_constants();" |
A maneira correta é utilizar apóstrofos (').
Variáveis em strings delimitadas por apóstrofos não são substituidas
pelo sh/bash.
$ php -r '$foo = get_defined_constants(); var_dump($foo);'
array(370) {
["E_ERROR"]=>
int(1)
["E_WARNING"]=>
int(2)
["E_PARSE"]=>
int(4)
["E_NOTICE"]=>
int(8)
["E_CORE_ERROR"]=>
[...] |
Se você estiver utilizando um shell diferente do sh/bash, você pode experimentar
comportamentos diferenciados. Sinta-se livre para abrir um aviso de bug ou enviar um e-mail
para phpdoc@lists.php.net.
Você vai rapidamente conseguir problemas quando tentar obter variáveis
do ambiente dentro do código ou quando utilizar barras invertidas para escape. Esteja
avisado.
Nota:
-r está disponível na SAPI CLI
SAPI mas não na SAPI CGI.
|
| -h | --help |
Com essa opção, você pode obter informações sobre a lista atual de
opções de linha de comando pequenas descrições sobre o que elas fazem.
|
| -? | --usage |
Apelido para --help.
|
O PHP executável pode ser utilizando para rodar scripts PHP absolutamente
independente de um servidor web. Se você está num sistema Unix, você pode acrescentar uma linha
especial na primeira linha de seu script e torná-lo executável, então o sistema operacional
saberá que programa deverá rodar o script. Na plataforma Windows, você pode
associar php.exe -q com o clique duplo em arquivos
.php ou fazer um arquivo batch para rodar
seus scripts através do PHP. A primeira linha acrescentada ao script nos Unix não
funcionam no Windows, por isso você não pode escrever programas independentes de plataforma desse jeito.
Um exemplo simples de como escrever um programa para a linha de comando segue abaixo:
Exemplo 23-1. Um script para rodar na linha de comando (script.php)
#!/usr/bin/php <?php
if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) { ?>
Este é um script de linha de comando com um parâmetro.
Uso: <?php echo $argv[0]; ?> <opcao>
<opcao> pode ser qualquer palavra que você queira imprimir. Com as opções --help, -help, -h ou -?, você pode obter essa ajuda.
<?php } else { echo $argv[1]; } ?>
|
|
No script acima, nós utilizamos uma primeira linha especial para indicar
que este arquivo precisa rodar pelo PHP. Como nós trabalhamos com a versão CLI
aqui, não serão impressos headers HTTP. Há duas variáveis que você precisa conhecer para escrever aplicações
em linha de comando com o PHP: $argc e
$argv. O primeiro é o número de argumentos mais
um (o nome do script executando). O segundo é um array
contendo os argumentos, começando com o nome do script no índice
zero ($argv[0]).
No programa acima é verificado se há apenas um argumento
fornecido. Se o argumento for --help,
-help, -h ou -?,
é impresso uma mensagem de ajuda, imprimindo o nome do script dinamicamente.
Qualquer outro argumento é exibido como informado.
Para rodar esse aplicativo nos Unix, basta torná-lo
executável e o chamar diretamente como
script.php exibaisso ou
script.php -h. No Windows, você pode fazer um
arquivo batch para esta tarefa:
Exemplo 23-2. Arquivo batch para rodar um script em linha de comando (script.bat) @c:\php\cli\php.exe script.php %1 %2 %3 %4 |
|
Assumindo que você nomeou o programa acima como
script.php, e que tem sua versão
CLI php.exe em
c:\php\cli\php.exe este arquivo batch
irá rodar com os seguintes parâmetros:
script.bat exibaisso ou
script.bat -h.
Veja também a documentação da extensão Readline
para mais funções que você pode usar
para incrementar suas aplicações para linha de comando em PHP.