Categorie
PHP

Eseguire PHP da riga di comando

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.

Nota: se si usa Windows e consigliabile inserire l’eseguibile PHP tra le variabili d’ambiente.

Cosa cambia

Sebbene condividano moti comportamenti esistono notevoli differenze tra la CLI SAPI rispetto alle vecchie CGI SAPI:

  1. 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).
  2. 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.
  3. 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.
  4. 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";" 
Note: In questa modalità prestare attenzione all'utilizzo delle virgolette nello script. Inoltre non devono essere utilizzati i tags PHP di apertura e chiusura, altrimenti si genererà un errore.

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.

Nota: Il nome dello script viene passato sempre come primo argomento allo script, quindi il numero minimo di $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.

Nota: nell'esempio precedente il files error.log si deve trovare (o verrà creato se non presente) nella directory da cui viene lanciato il comando.

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.

Risorse

www.php.net/manual/en/features.commandline.introduction.php

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.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *

Questo sito usa Akismet per ridurre lo spam. Scopri come i tuoi dati vengono elaborati.