A partire dalla versione 4.3.0, il PHP supporta un
nuovo tipo di SAPI (Server Application Programming Interface)
chiamata CLI che significa Interfaccia per la Linea di Comando (Command Line
Interface). Come il nome stesso suggerisce, questo tipo di SAPI
è mirato allo sviluppo di applicazioni shell (o desktop) con
PHP. Esistono alcune differenze tra la
CLI SAPI e le altre SAPI; queste saranno illustrate
nel corrente capitolo. Val la pena ricordare che
CLI e CGI sono differenti
SAPI sebbene condividano il medesimo comportamento in diverse situazioni.
La CLI SAPI è stata rilasciata per la prima volta con
PHP 4.2.0, ma era ancora sperimentale e quindi doveva essere
esplicitamente abilitata con --enable-cli nell'esecuzione di
./configure. A partire dal PHP 4.3.0 la
CLI SAPI non viene più considerata sperimentale e quindi l'opzione
--enable-cli è attivata per default. Vedere
--disable-cli per disabilitare l'opzione.
Dal PHP 4.3.0, il nome, la posizione, e l'esistenza di eseguibili CLI/CGI
differirà in base a come il PHP sarà installato sul sistema.
Per default quando si esegue il make, si compila sia la versione CLI sia la versione CGI
e saranno poste rispettivamente in sapi/cgi/php e sapi/cli/php
a partire dalla directory dei sorgenti. Occorre notare che entrambi gli eseguibili
sono chiamati php. Ciò che accade durante l'esecuzione di
dipende dalla linea di configurazione.
Se durante la configurazione si è scelto un modulo SAPI, tipo apxs, o si è attivato
--disable-cgi, l'eseguibile CLI viene copiato in
durante make install,
altrimenti in questa cartella sarà posto l'eseguibile CGI. Così, per esempio, se si ha
come parametro di configurazione --with--apxs allora l'eseguibile CLI
sarà copiato in {PREFIX}/bin/php durante make
install. Se si vuole evitare l'installazione dell'eseguibile CGI,
utilizzare make install-cli dopo make
install. In alternativa si può specificare --disable-cgi
nella linea di configurazione.
Nota:
Poichè sia --enable-cli sia
--enable-cgi sono abilitati per default, avere semplicemente
--enable-cli nella linea di configurazione non significa
necessariamente che l'eseguibile CLI sia copiato come {PREFIX}/bin/php
con l'esecuzione di make install.
Nel pacchetto per Windows, nelle versioni tra PHP 4.2.0 e PHP 4.2.3, l'eseguibile CLI
era presente come php-cli.exe, nella medesima cartella della versione CGI
php.exe. A partire dal PHP 4.3.0 nel pacchetto per Windows la versione CLI viene
distribuita come php.exe in una cartella a parte chiamata cli,
avendo perciò cli/php.exe.
A partire dal PHP 5, la versione CLI viene inserita nella cartella principale, con il nome
php.exe. La versione CGI sarà chiamata
php-cgi.exe.
Sempre dal PHP 5, sarà introdotto un nuovo file chiamato php-win.exe.
Questo è equivalente alla versione CLI, tranne che php-win non visualizzerà nulla
e quindi non vi sarà la finestra di console (non compare la fienstra dos nello schermo). Questo comportamento
è stato ripreso da php-gtk. Si dovrebbe configurare il PHP con
--enable-cli-win32.
Quale SAPI ho?:
Da shell, digitando php -v si avrà l'informazione di
quale php si tratta, CGI o CLI. Vedere anche la funzione
php_sapi_name()e la costante
PHP_SAPI per dettagli.
Nota:
Una pagina stile man di Unix è stata aggiunta in PHP 4.3.2. La si può
visualizzare digitando man php da linea di comando.
Le principali differenze tra la CLI SAPI e le altre
SAPI sono:
A differenza di CGI SAPI, non sono inviate in output
delle intestazioni.
Mentre nella CGI SAPI esiste un modo per sopprimere
le intestazioni, nella CLI SAPI non si ha una opzione
per abilitare le intestazioni.
Per default CLI parte in modalità silenziosa, si è mantenuto, comunque,
l'opzione -q e --no-header per motivi di compatibilità;
in questo modo si possono utlizzare i vecchi script CGI.
Non cambia la directory di lavoro in quella dello script.
(E' rimasta l'opzione -C e --no-chdir per compatibilità)
Messaggi di errore in formato testo (non formattati in HTML).
Esistono, inoltre, alcune direttive del php.ini che sono forzate nell'impostazione dalla CLI
SAPI poichè non hanno senso nell'ambiente di shell:
Tabella 43-1. Direttive del php.ini forzate
Direttiva | CLI SAPI valore di default | Commento |
---|
html_errors | FALSE |
E' difficile leggere i messaggi di errore nella shell quando
sono affogati in tag HTML prive di significato;
pertanto il default della direttiva è impostato a FALSE.
|
implicit_flush | TRUE |
E' desiderabile che ogni tipo di output proveniente da
print(), echo() e simili sia scritto
immediatamente e non venga bufferizzato. Tuttavia è ancora possibile
utilizzare le funzioni di controllo dell'output
se si desidera ritardare o manipolare lo standard output.
|
max_execution_time | 0 (unlimited) |
Considerate le svariate possibilità offerte da PHP
nell'ambiente di shell, il tempo massimo di esecuzione è stato impostato
a infinito. Mentre nelle applicazione scritte per il web i tempi di esecuzione
sono rapidi, le applicazioni di shell tendono ad avere tempi di esecuzione
molto più lunghi.
|
register_argc_argv | TRUE |
Poichè è impostato a TRUE nella CLI SAPI si ha sempre la possibilità di accedere alla variabili
argc (numero di argomenti passati all'applicazione)
e argv (matrice degli
argumenti).
A partire da PHP 4.3.0, quando si utilizza la CLI SAPI le variabili PHP $argc
e $argv sono sempre registrate e valorizzate in modo
appropriato. Prima di questa versione la creazione
di queste variabili era coerente con il comportamento delle versioni
CGI e MODULO le quali
richiedevano che la direttiva PHP
register_globals fosse impostata
a on. A prescindere dalla versione o dall'impostazione di
register_globals si può sempre accedere alle variabili
$_SERVER o
$HTTP_SERVER_VARS. Esempio:
$_SERVER['argv']
|
Nota:
Queste direttive non possono essere inizializate con altri valori
dal file di configurazione php.ini o da uno personalizzato (se specifictao). Questa è
una limitazione perchè questi valori di default sono applicati
dopo avere esaminato tutti i file di configurazione. Tuttavia i loro valori possono
essere cambiati durante l'esecuzione (operazione che non ha senso per queste direttive,
ad esempio register_argc_argv).
Per potere lavorare meglio con le shell, sono state definite le seguenti
costanti:
Tabella 43-2. Costanti specifiche per CLI
Costante | Descrizione |
---|
STDIN |
Un flusso già aperto allo stdin. Questo evita di
aprirlo con
<?php $stdin = fopen('php://stdin', 'r');
?>
|
Se si desidera leggere una singola linea dallo stdin, si
può utilizzare
<?php $line = trim(fgets(STDIN)); // reads one line from STDIN fscanf(STDIN, "%d\n", $number); // reads number from STDIN ?>
|
|
STDOUT |
Un flusso già aperto allo stdout. Questo evita di
aprirlo con
<?php
$stdout = fopen('php://stdout', 'w');
?>
|
|
STDERR |
Un flusso già aperto allo stderr. Questo evita di
aprirlo con
<?php
$stderr = fopen('php://stderr', 'w');
?>
|
|
Stante a quanto descritto non occorre più aprire in autonomia
flussi per, ad esempio, lo stderr, ma semplicemente si può
usare le costanti anzichè una nuova risorsa di flusso:
php -r 'fwrite(STDERR, "stderr\n");' |
Non occorre chiudere esplicitamente questi flussi, saranno chiusi automaticamente
dal PHP alla fine dello script.
La CLI SAPI non cambia la directory corrente in quella
dello script eseguito!
Il seguente esempio illustra la diferenza rispetto alla CGI SAPI:
<?php // Semplice esempio di test chiamato test.php echo getcwd(), "\n"; ?>
|
Quando si usa la versione CGI, si avrà il seguente output:
$ pwd
/tmp
$ php -q another_directory/test.php
/tmp/another_directory |
Questo evidenzia chiaramente come il PHP cambi la
directory corrente con quella in cui si trova lo script.
Utilizzando la versione CLI SAPI abbiamo:
$ pwd
/tmp
$ php -f another_directory/test.php
/tmp |
Questo permette una grande flessibilità nello scrivere tools in
PHP.
Nota:
La CGI SAPI supporta il comportamento
della CLI SAPI attivando l'opzione -C
quando viene eseguito da linea di comando.
L'elenco completo delle opzioni del PHP disponibili da linea di comando
può essere visualizzato in qualsiasi momento eseguendo il PHP
con l'opzione -h:
Usage: php [options] [-f] <file> [--] [args...]
php [options] -r <code> [--] [args...]
php [options] [-B <begin_code>] -R <code> [-E <end_code>] [--] [args...]
php [options] [-B <begin_code>] -F <file> [-E <end_code>] [--] [args...]
php [options] -- [args...]
-a Run interactively
-c <path>|<file> Look for php.ini file in this directory
-n No php.ini file will be used
-d foo[=bar] Define INI entry foo with value 'bar'
-e Generate extended information for debugger/profiler
-f <file> Parse <file>.
-h This help
-i PHP information
-l Syntax check only (lint)
-m Show compiled in modules
-r <code> Run PHP <code> without using script tags <?..?>
-B <begin_code> Run PHP <begin_code> before processing input lines
-R <code> Run PHP <code> for every input line
-F <file> Parse and execute <file> for every input line
-E <end_code> Run PHP <end_code> after processing all input lines
-H Hide any passed arguments from external tools.
-s Display colour syntax highlighted source.
-v Version number
-w Display source with stripped comments and whitespace.
-z <file> Load Zend extension <file>.
args... Arguments passed to script. Use -- args when first argument
starts with - or script is read from stdin |
La vesione CLI SAPI ha tre differenti modi per
eseguire il codice PHP:
Dire al PHP di eseguire certi file.
php my_script.php
php -f my_script.php |
Entrambi i metodi (con o senza l'opzione -f) eseguono il
file my_script.php. Si può scegliere qualsiasi nome per lo
script da eseguire - non è obbligatorio che gli script PHP finiscano
con l'estensione .php, ma possono avere qualsiasi nome
o estensione che si desideri.
Passare il codice PHP da eseguire direttamente da linea di
comando.
php -r 'print_r(get_defined_constants());' |
Occorre prestare molta attenzione alla sostituzione delle variabili di shell
e all'uso degli apici.
Nota:
Osservando con attenzione l'esempio si nota l'assenza dei tag di inizio e fine!
L'opzione -r non li richiede. L'uso dei tag genera un
errore di parsing.
Si può passare il codice PHP da eseguire via standard input
(stdin).
Questo da la possibilità di generare dinamicamente del codice
PHP e passarlo all'eseguibile, come illustrato nel seguente
esempio (fittizio):
$ some_application | some_filter | php | sort -u >final_output.txt |
Non si possono combinare tra loro questi tre metodi di esecuzione del codice.
Come qualsiasi applicazione di shell, anche l'eseguibile PHP
accetta diversi argomenti, ma anche lo script PHP può ricevere
argomenti. Il numero degli argomenti passabili allo script non è
limitato dal PHP (si rammenta che la shell ha un limite
nel numero di caratteri che possono essere passati; solitamente non si raggiunte
questo limite). Gli argomenti passati allo script sono disponibili nell'array
$argv. L'indice zero contiene sempre il nome dello script
(che è - nel caso in cui il codice PHP
provenda o dallo standard input o dalla linea di comando con l'opzione
-r). La seconda variabile globale registrata è
$argc la quale contiene il numero degli elementi nella matrice
$argv (non è
il numero degli argomenti passati allo script).
Fino a quando gli argomenti passati allo script non iniziano con
il carattere - non si deve prestare alcuna cautela.
Tuttavia se si passa allo script argomenti che iniziano con
- si hanno dei problemi perchè lo stesso PHP
ritiene di doverli gestire. Per evitare ciò occorre utilizzare il separatore di argomenti
--. Dopo che il PHP ha incontrato questo separatore,
ogni argomento verrà passato
direttamente allo script.
# Questo non visualizzerà il codice passato, ma l'elenco delle opzioni
$ php -r 'var_dump($argv);' -h
Usage: php [options] [-f] <file> [args...]
[...]
# Questo passerà il '-h'allo script ed eviterà al PHP di visualizzare le opzioni
$ php -r 'var_dump($argv);' -- -h
array(2) {
[0]=>
string(1) "-"
[1]=>
string(2) "-h"
} |
Tuttvia esiste un'altro modo per eseguire gli script PHP.
Si può scrivere uno script la cui prima riga inizi con
#!/usr/bin/php. Seguendo questa regola si può posizionare
il normale codice PHP tra i tag di apertura e chiusura
del PHP. Una volta impostati correttamente gli attributi
del file (ad esempio chmod +x test) lo script può essere eseguito
come una normale shell o script perl:
#!/usr/bin/php <?php var_dump($argv); ?>
|
Assumento che questo file sia chiamato
test nella directory
corrente, si può eseguire:
$ chmod +x test
$ ./test -h -- foo
array(4) {
[0]=>
string(6) "./test"
[1]=>
string(2) "-h"
[2]=>
string(2) "--"
[3]=>
string(3) "foo"
} |
Come si può notare in questo caso non vi è necessità di prestare attenzione nel passare
i parametri che iniziano con
-.
I parametro lunghi sono disponibili dal PHP 4.3.3.
Tabella 43-3. Opzioni della linea di comando,
Parametro | Parametro lungo | Descrizione |
---|
-a | --interactive |
Esegue il PHP in modo interattivo.
|
-c | --php-ini |
Con questa opzione si può sia specificare la directory in cui cercare
il php.ini o si può specificare un file INI personalizzato
(che non deve necessariamente chiamarsi php.ini), ad esempio:
$ php -c /custom/directory/ my_script.php
$ php -c /custom/directory/custom-file.ini my_script.php |
Se non si specifica questa opzione, il file viene ricercato nelle
directory di default.
|
-n | --no-php-ini |
Ignora del tutto il php.ini. Opzione disponibile dal PHP 4.3.0.
|
-d | --define |
Questa opzione permette di impostare valori personalizzati per qualsiasi
delle direttive di configurazione previste in php.ini. La sintassi è:
-d configuration_directive[=value] |
Esempi (le linee vanno a capo per motivi di layout):
# Omettendo il valore si imposta la direttiva data a "1"
$ php -d max_execution_time
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(1) "1"
# Passando un valore vuoto si imposta la direttiva a ""
php -d max_execution_time=
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(0) ""
# La direttiva di configurazione viene impostata a qualsiasi valore passato dopo il carattere '='
$ php -d max_execution_time=20
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(2) "20"
$ php
-d max_execution_time=doesntmakesense
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
string(15) "doesntmakesense" |
|
-e | --profile-info |
Genera informazioni estese per il debugger/profiler.
|
-f | --file |
Analizza ed esegue il file passato con l'opzione -f.
Questo parametro è opzionale e può essere omesso. Basta fornire il
nome del file da eseguire.
|
-h e -? | --help e --usage |
Con questa opzione si ha l'elenco dei comandi di linea
ed una breve descrizione di questi.
|
-i | --info |
Questa opzione della linea di comando richiama la funzione phpinfo(), e ne
visualizza il risultato. Se il PHP non funziona correttamente, è opportuno
utilizzare php -i per verificare se sono visualizzati messaggi di errore
prima o al posto della tabella con le informazioni.
Fare attenzione quando si usa la modalità CGI, l'output è in formato HTML e quindi abbastanza
abbondante.
|
-l | --syntax-check |
Questa opzione fornisce un metodo pratico per eseguire un controllo sintattico
di un dato codice PHP. Se il controllo ha successo, verrà visualizzato il testo
No syntax errors detected in <filename>
e alla shell sarà restituito il codice
0. Se si rilevano errori si avrà il testo Errors parsing
<filename>, inoltre si avranno anche i messaggi di errore del parser
ed alla shell sarà restituito il codice
255.
Questa opzione non rileva errori fatali (tipo funzioni non definite). Occorre
utilizzare l'opzione -f se si desidera rilevare gli errori fatali.
Nota:
Questa opzione non è abbinabile all'opzione -r.
|
-m | --modules |
Utilizzare questa opzione per visualizzare i moduli PHP e di Zend
integrati (e quindi caricati):
$ php -m
[PHP Modules]
xml
tokenizer
standard
session
posix
pcre
overload
mysql
mbstring
ctype
[Zend Modules] |
|
-r | --run |
Questa opzione permette l'esecuzione di codice PHP direttamente
da linea di comando. I tag PHP di apertura e di chiusura
(<?php e ?>)
non sono necessari anzi, se presenti, causano un
errore del parser.
Nota:
Quando si utilizza questo metodo occorre prestare attenzione ad evitare
collisioni con la sostituzione delle varibili eseguita dalla shell
sulla linea di comando.
Ecco un esempio che visualizza un errore di parsing
$ php -r "$foo = get_defined_constants();"
Command line code(1) : Parse error - parse error, unexpected '=' |
In questo caso il problema è dovuto alla sostituzione della variabile
eseguita da sh/bash anche quando si usano i doppi apici ".
Poichè la viriabile $foo non è definita, essa
verrà espansa con 'niente' generando il seguente codice
PHP:
$ php -r " = get_defined_constants();" |
Il metodo corretto richiede l'uso dell'apice singolo '.
Le variabili racchiuse in stringhe delimite dall'apice singolo non
vengono espanse da 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 si utilizzano shell differenti rispetto a sh/bash, si potrebbe incorrere
in altri problemi. In tal caso aprite una segnalazione di errore a
http://bugs.php.net/
Tuttavia si può facilmente incorrere in problemi nell'avere variabili
di shell nel codice o nell'utilizzare le barre rovesciate (backslash) per l'escape.
Siete avvertiti.
Nota:
L'opzione -r è disponibile solo nella CLI
SAPI e non nella CGI SAPI.
|
-B | --process-begin |
Codice PHP da eseguirsi prima di processare stdin. Aggiunto in PHP 5.
|
-R | --process-code |
Esegue il codice PHP per ogni linea di input. Aggiunto in PHP 5.
In questa modalità si hanno due variabili speciali:
$argn ed $argi.
$argn contiene la linea PHP in elaborazione al momento,
mentre $argi contiene il numero
di linea.
|
-F | --process-file |
Esegue il file PHP per ogni linea di input. Aggiunto in PHP 5.
|
-E | --process-end |
Codice PHP da eseguirsi dopo il processamento dell'input. Aggiunto in PHP 4.
Esempio di utilizzo delle opzioni -B, -R e
-E per contare il numero di linea di un
progetto.
$ find my_proj | php -B '$l=0;' -R '$l += count(@file($argn));' -E 'echo "Total Lines: $l\n";'
Total Lines: 37328 |
|
-s | --syntax-highlight e --syntax-highlighting |
Visualizza il sorgente con sintassi colorata.
Questa opzione utilizza il meccanismo interno di parsing dei file e produce
una versione HTML del sorgente e la dirige verso lo
standard output. Occore notare che questa funzione genera dei blocchi di
tag HTML
<code> [...] </code> e non le intestazione HTML.
Nota:
Questa opzione non funziona abbinata all'opzione
-r.
|
-v | --version |
Visualizza le versioni di PHP, PHP SAPI, e Zend nello standard output, ad esempio:
$ 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 |
|
-w | --strip |
Visualizza il sorgente senza gli spazi e i commenti.
Nota:
Questa opzione non funziona abbinata all'opzione
-r.
|
-z | --zend-extension |
Carica l'estensione Zend. Soltano se si fornisce un nome di file, il PHP tenta
di caricare l'estensione dal corrente percorso di default delle librerie
(solitamente, sui sistemi Linux, /etc/ld.so.conf).
Se si fornisce un nome di file con percorso assoluto, ls libreria non
sarà cercata nella directory di default. Un nome di file con percorso relativo
indica al PHP di tentare di caricare l'estensione con
percorso relativo alla directory corrente.
|
L'eseguibile PHP può essere utilizzato per eseguire script PHP in modo indipendente
dal server web. Se ci si trova su sistemi Unix, si può aggiungere una prima linea
speciale allo script PHP e renderlo eseguibile, in questo modo il sistema
sa quale programma deve interpretare lo script. Sui sistemi Windows si può
associare php.exe all'estensione
.php, o si può scrivere un batch per eseguire
gli script tramite PHP. La prima riga inserita per i sistemi Unix non crea
problemi in Windows, in questo modo si possono scrivere batch multi-piattaforma.
Seguirà un semplice esempio di programma PHP da linea di comando.
Esempio 43-1. Script sviluppato per essere esguito da linea di comando (script.php)
#!/usr/bin/php <?php
if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) { ?>
Questo è uno script PHP da linea di comando con una opzione.
Utilizzo: <?php echo $argv[0]; ?> <opzione>
<opzione> può essere qualsiasi parola che si desidera stampata. Con --help, -help, -h, o -? si ottiene questo aiuto. <?php } else { echo $argv[1]; } ?>
|
|
Nello script precedente, abbiamo utilizzato la prima riga per indicare
che questo file deve essere interpretato dal PHP. Poichè qui lavoriamo con la versione CLI
non vengono prodotte intestazioni HTTP. Esistono due variabili che si possono
utilizzare nelle applicazioni PHP da linea di comando:
$argc e $argv. La
prima è il numero di argomenti più uno (il nome dello script).
La seconda è una matrice contenente gli argomenti, iniziando dal nome
dello script all'indice zero ($argv[0]).
Nel programma precedente abbiamo verificato se i parametri passati erano di più o di meno
di uno. Inoltre se l'argomento è --help,
-help, -h oppure -?,
si visualizza un messaggio di aiuto, visualizzando in modo dinamico il nome dello script.
Se si riceve un argomento differente questo sarà visualizzato.
Se si desidera eseguire lo script precedente su Unix, occorre,
per prima cosa, renderlo eseguibile, e quindi richiamarlo con
script.php echothis oppure
script.php -h. Su Windows occorre scrivere un batch
per ottenere questo risultato:
Esempio 43-2. File batch per eseguire uno script PHP da linea di comando (script.bat) @c:\php\cli\php.exe script.php %1 %2 %3 %4 |
|
Assumendo che programma precedente sia chiamato
script.php, che la versione
CLI di php.exe sia in
c:\php\cli\php.exe questo batch eseguirà
lo script con le opzioni passate:
script.bat echothis oppure
script.bat -h.
Vedere anche la documentazione del modulo
Readline per informazioni su funzioni
che possono essere utilizzate per migliorare le applicazioni da linea di comando.