PHP
Command Line Interface (CLI)
Ricerca…
Gestione degli argomenti
Gli argomenti vengono passati al programma in un modo simile alla maggior parte dei linguaggi in stile C. $argc
è un numero intero che contiene il numero di argomenti incluso il nome del programma e $argv
è un array contenente argomenti per il programma. Il primo elemento di $argv
è il nome del programma.
#!/usr/bin/php
printf("You called the program %s with %d arguments\n", $argv[0], $argc - 1);
unset($argv[0]);
foreach ($argv as $i => $arg) {
printf("Argument %d is %s\n", $i, $arg);
}
Chiamando l'applicazione sopra con php example.php foo bar
(dove example.php contiene il codice precedente) si otterrà il seguente output:
Hai chiamato il programma example.php con 2 argomenti
L'argomento 1 è foo
L'argomento 2 è bar
Si noti che $argc
e $argv
sono variabili globali, non variabili superglobali. Devono essere importati nello scope locale usando la parola chiave global
se sono necessari in una funzione.
Questo esempio mostra come gli argomenti vengono raggruppati quando vengono utilizzati gli escape come ""
o \
.
Script di esempio
var_dump($argc, $argv);
Riga di comando
$ php argc.argv.php --this-is-an-option three\ words\ together or "in one quote" but\ multiple\ spaces\ counted\ as\ one
int(6)
array(6) {
[0]=>
string(13) "argc.argv.php"
[1]=>
string(19) "--this-is-an-option"
[2]=>
string(20) "three words together"
[3]=>
string(2) "or"
[4]=>
string(12) "in one quote"
[5]=>
string(34) "but multiple spaces counted as one"
}
Se lo script PHP viene eseguito con -r
:
$ php -r 'var_dump($argv);'
array(1) {
[0]=>
string(1) "-"
}
Oppure il codice è stato convogliato in STDIN di php
:
$ echo '<?php var_dump($argv);' | php
array(1) {
[0]=>
string(1) "-"
}
Gestione di input e output
Quando vengono eseguiti dalla CLI, le costanti STDIN , STDOUT e STDERR sono predefinite. Queste costanti sono handle di file e possono essere considerati equivalenti ai risultati dell'esecuzione dei seguenti comandi:
STDIN = fopen("php://stdin", "r");
STDOUT = fopen("php://stdout", "w");
STDERR = fopen("php://stderr", "w");
Le costanti possono essere utilizzate ovunque sia un handle di file standard:
#!/usr/bin/php
while ($line = fgets(STDIN)) {
$line = strtolower(trim($line));
switch ($line) {
case "bad":
fprintf(STDERR, "%s is bad" . PHP_EOL, $line);
break;
case "quit":
exit;
default:
fprintf(STDOUT, "%s is good" . PHP_EOL, $line);
break;
}
}
Gli indirizzi del flusso incorporato di cui si fa riferimento in precedenza ( php://stdin
, php://stdout
e php://stderr
) possono essere utilizzati al posto dei nomi di file nella maggior parte dei contesti:
file_put_contents('php://stdout', 'This is stdout content');
file_put_contents('php://stderr', 'This is stderr content');
// Open handle and write multiple times.
$stdout = fopen('php://stdout', 'w');
fwrite($stdout, 'Hello world from stdout' . PHP_EOL);
fwrite($stdout, 'Hello again');
fclose($stdout);
In alternativa, è possibile utilizzare anche readline () per l'input e per l'output è anche possibile utilizzare echo o print o qualsiasi altra funzione di stampa di stringhe.
$name = readline("Please enter your name:");
print "Hello, {$name}.";
Codici di ritorno
Il costrutto di uscita può essere utilizzato per passare un codice di ritorno all'ambiente di esecuzione.
#!/usr/bin/php
if ($argv[1] === "bad") {
exit(1);
} else {
exit(0);
}
Per impostazione predefinita, verrà restituito un codice di uscita pari a 0
se non ne viene fornito nessuno, ovvero l' exit
è uguale a exit(0)
. Poiché exit
non è una funzione, le parentesi non sono necessarie se non viene passato alcun codice di ritorno.
I codici di ritorno devono essere compresi tra 0 e 254 (255 è riservato da PHP e non deve essere utilizzato). Per convenzione, l'uscita con un codice di ritorno di 0
indica al programma chiamante che lo script PHP è stato eseguito correttamente. Utilizzare un codice di ritorno diverso da zero per comunicare al programma chiamante che si è verificata una condizione di errore specifica.
Gestione delle opzioni del programma
Le opzioni del programma possono essere gestite con la funzione getopt()
. Funziona con una sintassi simile al comando getopt
POSIX, con supporto aggiuntivo per le opzioni lunghe in stile GNU.
#!/usr/bin/php
// a single colon indicates the option takes a value
// a double colon indicates the value may be omitted
$shortopts = "hf:v::d";
// GNU-style long options are not required
$longopts = ["help", "version"];
$opts = getopt($shortopts, $longopts);
// options without values are assigned a value of boolean false
// you must check their existence, not their truthiness
if (isset($opts["h"]) || isset($opts["help"])) {
fprintf(STDERR, "Here is some help!\n");
exit;
}
// long options are called with two hyphens: "--version"
if (isset($opts["version"])) {
fprintf(STDERR, "%s Version 223.45" . PHP_EOL, $argv[0]);
exit;
}
// options with values can be called like "-f foo", "-ffoo", or "-f=foo"
$file = "";
if (isset($opts["f"])) {
$file = $opts["f"];
}
if (empty($file)) {
fprintf(STDERR, "We wanted a file!" . PHP_EOL);
exit(1);
}
fprintf(STDOUT, "File is %s" . PHP_EOL, $file);
// options with optional values must be called like "-v5" or "-v=5"
$verbosity = 0;
if (isset($opts["v"])) {
$verbosity = ($opts["v"] === false) ? 1 : (int)$opts["v"];
}
fprintf(STDOUT, "Verbosity is %d" . PHP_EOL, $verbosity);
// options called multiple times are passed as an array
$debug = 0;
if (isset($opts["d"])) {
$debug = is_array($opts["d"]) ? count($opts["d"]) : 1;
}
fprintf(STDOUT, "Debug is %d" . PHP_EOL, $debug);
// there is no automated way for getopt to handle unexpected options
Questo script può essere testato in questo modo:
./test.php --help
./test.php --version
./test.php -f foo -ddd
./test.php -v -d -ffoo
./test.php -v5 -f=foo
./test.php -f foo -v 5 -d
Nota che l'ultimo metodo non funzionerà perché -v 5
non è valido.
Nota: A partire da PHP 5.3.0,
getopt
è indipendente dal sistema operativo, funziona anche su Windows.
Limita l'esecuzione dello script alla riga di comando
La funzione php_sapi_name()
e la costante PHP_SAPI
restituiscono entrambi il tipo di interfaccia ( S erver API ) che viene utilizzata da PHP. Possono essere utilizzati per limitare l'esecuzione di uno script alla riga di comando, controllando se l'output della funzione è uguale a cli
.
if (php_sapi_name() === 'cli') {
echo "Executed from command line\n";
} else {
echo "Executed from web browser\n";
}
La funzione drupal_is_cli()
è un esempio di una funzione che rileva se uno script è stato eseguito dalla riga di comando:
function drupal_is_cli() {
return (!isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0)));
}
Esecuzione del tuo script
Su Linux / UNIX o Windows, uno script può essere passato come argomento all'eseguibile di PHP, con le opzioni e gli argomenti di tale script che seguono:
php ~/example.php foo bar
c:\php\php.exe c:\example.php foo bar
Questo passa foo
e bar
come argomenti per example.php
.
Su Linux / UNIX, il metodo preferito di esecuzione degli script consiste nell'utilizzare uno shebang (ad esempio #!/usr/bin/env php
) come prima riga di un file e impostare il bit eseguibile sul file. Supponendo che lo script sia nel tuo percorso, puoi chiamarlo direttamente:
example.php foo bar
L'uso di /usr/bin/env php
rende l'eseguibile di PHP da trovare usando il PATH. Seguendo il modo in cui PHP è installato, potrebbe non trovarsi nello stesso posto (come /usr/bin/php
o /usr/local/bin/php
), diversamente da env
che è comunemente disponibile da /usr/bin/env
.
Su Windows, potresti ottenere lo stesso risultato aggiungendo la directory di PHP e lo script al PATH e modificando PATHEXT per consentire a .php
di essere rilevato usando il PATH. Un'altra possibilità è quella di aggiungere un file denominato example.bat
o example.cmd
nella stessa directory dello script PHP e scrivere in questa riga:
c:\php\php.exe "%~dp0example.php" %*
Oppure, se hai aggiunto la directory di PHP nel PERCORSO, per un comodo utilizzo:
php "%~dp0example.php" %*
Differenze comportamentali sulla riga di comando
Quando si esegue dalla CLI, PHP presenta alcuni comportamenti diversi rispetto a quando viene eseguito da un server Web. Queste differenze dovrebbero essere tenute a mente, specialmente nel caso in cui lo stesso script possa essere eseguito da entrambi gli ambienti.
- Nessuna modifica alla directory Quando si esegue uno script da un server Web, la directory di lavoro corrente è sempre quella dello script stesso. Il codice
require("./stuff.inc");
presume che il file si trovi nella stessa directory dello script. Sulla riga di comando, la directory di lavoro corrente è la directory in cui ti trovi quando chiami lo script. Gli script che verranno chiamati dalla riga di comando dovrebbero sempre utilizzare percorsi assoluti. (Nota le costanti magiche__DIR__
e__FILE__
continuano a funzionare come previsto, e restituiscono il percorso dello script.) - Nessun buffer di output Le direttive
php.ini
output_buffering
eimplicit_flush
output_buffering
sufalse
etrue
, rispettivamente. Il buffering è ancora disponibile, ma deve essere abilitato esplicitamente, altrimenti l'output verrà sempre visualizzato in tempo reale. - Nessun limite di tempo La direttiva
php.ini
max_execution_time
è impostata su zero, quindi gli script nonmax_execution_time
per impostazione predefinita. - Nessun errore HTML Nel caso in cui sia stata abilitata la direttiva
php.ini
html_errors
, essa verrà ignorata sulla riga di comando. - È possibile caricare diversi
php.ini
. Quando usi php da cli, puoi utilizzarephp.ini
diversi dal server web. Puoi sapere quale file sta usando eseguendophp --ini
.
Esecuzione di web server integrato
Dalla versione 5.4, PHP è dotato di server integrato. Può essere utilizzato per eseguire l'applicazione senza necessità di installare altri server http come nginx o apache. Il server integrato è progettato solo in ambiente controller per scopi di sviluppo e test.
Può essere eseguito con comando php -S:
Per testarlo creare il file index.php
contenente
<?php
echo "Hello World from built-in PHP server";
ed esegui il comando php -S localhost:8080
Ora dovresti essere in grado di vedere il contenuto nel browser. Per verificare ciò, accedere a http://localhost:8080
Ogni accesso dovrebbe risultare nella voce di registro scritta sul terminale
[Mon Aug 15 18:20:19 2016] ::1:52455 [200]: /
Edge Cases of getopt ()
Questo esempio mostra il comportamento di getopt
quando l'input dell'utente non è comune:
getopt.php
var_dump(
getopt("ab:c::", ["delta", "epsilon:", "zeta::"])
);
Riga di comando della shell $ php getopt.php -a -a -bbeta -b beta -cgamma --delta --epsilon --zeta --zeta=f -c gamma
array(6) {
["a"]=>
array(2) {
[0]=>
bool(false)
[1]=>
bool(false)
}
["b"]=>
array(2) {
[0]=>
string(4) "beta"
[1]=>
string(4) "beta"
}
["c"]=>
array(2) {
[0]=>
string(5) "gamma"
[1]=>
bool(false)
}
["delta"]=>
bool(false)
["epsilon"]=>
string(6) "--zeta"
["zeta"]=>
string(1) "f"
}
Da questo esempio, si può vedere che:
- Le opzioni individuali (senza due punti) portano sempre un valore booleano di
false
se abilitato. - Se viene ripetuta un'opzione, il rispettivo valore nell'output di
getopt
diventerà un array. - Le opzioni di argomento richieste (due punti) accettano uno spazio o nessuno spazio (come le opzioni di argomento facoltativo) come separatore
- Dopo un argomento che non può essere mappato in nessuna opzione, anche le opzioni dietro non verranno mappate.