Dalla versione 4.3, PHP supporta un nuovo tipo di SAPI (Server Application Programming Interface)
chiamata CLI ( Command Line Interface). Come è facile intuire si tratta di un modo per utilizzare PHP dalla riga di comando di sistema (la shell di Linux o il prompt dei comandi di Windows). Questa modalità oltre ad essere indicata per automatizzare e programmare l’esecuzione dei nostri scripts (CRON), ci offre la non trascurabile possibilità di usare scripts PHP al di fuori di un server web (Apache, IIS etc..). Inoltre ci evita la necessità di conoscere un altro linguaggio tipo Perl o Bash per eseguire tali operazioni.
PHP CLI (o CLI SAPI) è stata rilasciata per la prima volta in via sperimentale con PHP 4.2.0 per poi divenire effettivamente supportata dalla versione 4.3.
PHP CLI viene installata di default, con le nuove versioni di PHP, non si dovrà quindi eseguire nessuna operazione aggiuntiva.
Cosa cambia
Sebbene condividano moti comportamenti esistono notevoli differenze tra la CLI SAPI rispetto alle vecchie CGI SAPI:
- Diversamente da PHP CGI (o CGI SAPI), non viene scritto nessun header nell’output. Difatti CLI viene avviato di default in modalità silenziosa (quiet mode).
- PHP CLI non cambia la directory corrente. La directory corrente per lo script sarebbe la directory da cui battiamo il comando . La funzione
getcwd()
(get current working directory) ci mostra appunto questo particolare restituendo la directory da cui lo script viene lanciato diversamente a CGI SAPI che invece restituisce la directory in cui lo script si trova. -
Alcune direttive del php.ini saranno sovrascritte CLI SAPI perché non hanno senso nell’ambiente di shell:
Direttiva Valore default Commento html_error FALSE Naturalmente di default saranno tolti i tags HTML sui messaggi di errore nella shell, vista l’inutilità oltre al fatto che ne renderebbero difficile la lettura. implicit_flush TRUE Qualsiasi output è preferibile scriverlo immediatamente anzichè memorizzarlo in un qualsiasi buffer prima di essere scritto. max_execution_time 0 (illimitato) A differenza degli scripts web ai quali è bene dare un limite di esecuzione, gli scripts di shell di solito hanno bisogno di tempi più lunghi, quindi di default non viene dato nessun limite. register_argc_argv TRUE Questa direttiva impostata su TRUE dice a PHP di dichiarare le variabili globali argv ed argc responsabili di contenere rispettivamente gli argomenti passati all’applicazione ed un array degli argomenti attuali. max_input_time FALSE Non sono supportati GET, POST o uploads di files. Nota: queste direttive non possono essere inizializzate con valori diversi nel php.ini o in altro file di configurazione, visto che acquisiranno questi valori dopo il parsing di tutti i files di configurazione. Durante l’esecuzione del programma invece, i valori potranno essere modificati. - Come vedremo più tardi sono state definite una serie di costanti per i flussi di I/O.
Utilizzo
PHP CLI oltre ad essere molto semplice da usare è anche particolarmente flessibile. Difatti è disponibile una vasta gamma di opzioni che brevità non elencherò in questo articolo.
Il modo più semplice di di usare PHP CLI è quello di battere “php myScript.php
” nella riga di comando. Il nome del file non dovrà avere necessariamente l’estensione .php, ma qualunque estensione è ammessa.
Esecuzione sotto Linux
Consideriamo questo semplice script (myScript.php):
#!/usr/bin/php -q <?php $i = 0; while ($i<10) { print $i."n"; sleep(1); $i++; } ?>
La prima riga indica il percorso del motore PHP che dovrà eseguire il parsing dello script (nel caso si trovi in altra cartella cambiare percorso).
Non dimentichiamoci di impostare i permessi al file:
$ chmod 755 myScript.php
Per eseguire lo script basterà poi battere:
$ ./myScript.php
Esecuzione sotto Windows
Per eseguire scripts PHP CLI su macchine Windows basterà modificare (oppure omettere del tutto) il percorso dell'esecutore PHP nella prima linea che di solito è:
#!C:phpphp.exe
Quindi battere sul prompt dei comandi:
> php myScript.php
Immettere il codice sulla linea di comando
Possiamo anche eseguire scripts PHP CLI immettendo il codice direttamente sulla riga di comando, utilizzando l'opzione -r:
php -r "echo "Esempio argomento -r.n";"
Argomenti
PHP CLI prevede la possibilità di passare degli argomenti da riga di comando, in questo la sintassi sarà:
php myScript.php arg1 arg2 arg3
La variabile $argc
contiene il numero di argomenti passati allo script corrente durante l'esecuzione da riga di comando. Mentre l'array $argv
è il contenitore degli argomenti stessi. Naturalmente queste variabili non saranno disponibili se la direttiva register_argc_argv è disabilitata.
$argc
è 1 ed $argv[0]
conterrà sempre questa informazione.
#!C:phpphp.exe -q <?php echo "Numero argomenti: ".$argc."n"; for($i=0; $i<$argc; $i++) { echo "argv[$i]: $argv[$i]n"; } ?>
Input e output streams
Oltre a passare dei parametri all'esecuzione dello script, abbiamo la possibilità di ottenere degli input durante l'esecuzione dello stesso. In PHP CLI ci sono tre flussi (streams) che ci permettono di interagire con l'applicazione, più o meno alle stesso modo con cui interagiamo con una risorsa restituita da fopen()
.
Costante | Flusso | Descrizione |
---|---|---|
STDIN | php://stdin (read) | I dati immessi verso l'applicazione, corrisponde all'immissione da tastiera (sola lettura) |
STDOUT | php://stdout (write) | Lo stream sul quale l'applicazione scrive l'output |
STDERR | php://stderr (write) | Stream utilizzato epr separare i messaggi di errore dall'output normale. |
Come detto questi stream sono trattati come files, possiamo quindi utilizzare funzioni tipo fopen()
, fread()
, fwrite()
, fgets()
etc.. per interagire con gli streams.
Condideriamo questo esempio, invece di utlizzare echo
o print
utilizzo lo stream STDOUT:
<?php //echo "Ciao mondo!"; fwrite(STDOUT, "Ciao mondo!"); ?>
Vediamo ora in azione anche lo stream STDIN ha permetterà in inserire input allo script durante la sua esecuzione:
<?php fwrite(STDOUT, "Inserisci il tuo nome:n"); $name = fgets(STDIN); fwrite(STDOUT, "Inserisci la tua etàn"); $age = fgets(STDIN); fwrite(STDOUT, "Ciao $name hai $age anni"); ?>
Infine un esempio per l'utilizzo dello stream STDERR. Possiamo pensare di gestire i messaggi di errore attraverso una funzione personalizzata utilizzando set_error_handler()
:
<?php set_error_handler("ErrorHandler"); function ErrorHandler($errno, $errstr, $errfile, $errline) { fwrite(STDERR,"$errstr in $errfile on $errlinen"); } ?>
Possiamo anche utilizzare gli streams nella riga di comando per dirottare l'output ad una determinata destinazione. Per esempio il seguente comando scriverà gli eventuali messaggi di errore di myScript.php in error.log
php myScript.php 2> error.log
Il numero 2 è un gancio per identificare lo stream STDERR (1 per STDOUT). Il carattere ">" è utilizzato appunto per spostare l'output ad altra destinazione.
Conclusioni
La stragrande maggioranza degli scenari di utilizzo di PHP naturalmente è in un ambiente Web, tuttavia trovo la possibilità offertaci dal linguaggio di poter eseguire scripts da shell particolarmente interessante.
Eseguire backups, eliminare files obsoleti da eventuali archivi, analizzare files di log, inviare emails a migliaia di iscritti ad una mailing list sono solo alcuni esempi in cui PHP CLI ci può tornare molto utile.
Una risposta su “Eseguire PHP da riga di comando”
Nota: da linea di comando si devono usare le sequenze di escape, per le virgolette (\”) e per il backslash stesso (\\n):
php -r “echo \”Esempio argomento -r.\\n\”;”
Verificato con php 5.4.16 in ambiente Windows XP e php 5.4.24 in ambiente Mac OS X.