If a module SAPI is chosen during configure, such as apxs, or the --disable-cgi option is used, the CLI is copied to {PREFIX}/bin/php during make install otherwise the CGI is placed there.
versus
Changed CGI install target to php-cgi and 'make install' to install CLI when CGI is selected. (changelog for 5.2.3)
http://www.php.net/ChangeLog-5.php#5.2.3
PHP auf der Kommandozeile
Seit Version 4.3.0 unterstützt PHP einen neuen Typ SAPI (Server Application Programming Interface) namens CLI (Command Line Interface). Wie der Name schon verrät, liegt das Hauptaugemerk dieses SAPI-Typs auf der Entwicklung von Anwendungen für die Kommandozeile (und auch den Desktop) mit PHP. Es gibt etliche Unterschiede zwischen dem CLI SAPI und anderen SAPIs, die in diesem Kapitel beschrieben werden. Es ist erwähnenswert, dass CLI und CGI verschiedene SAPIs sind, obwohl sie viele Verhaltensweisen teilen.
Das CLI SAPI wurde zum ersten Mal mit PHP 4.2.0 eingeführt, war aber noch experimentell und musste explizit mit --enable-cli beim ./configure-Aufruf eingeschaltet werden. Seit PHP 4.3.0 ist das CLI SAPI nicht länger experimentell und die Option --enable-cli standardmäßig auf aktiviert. Sie können --disable-cli benutzen, um es auszuschalten.
Von PHP 4.3.0 an werden Namen, Pfade und Vorhandensein der CLI/CGI-Binaries voneinander abweichen, abhängig davon, wie PHP auf Ihrem System installiert ist. Standarmäßig werden nach dem Aufruf von make sowohl CGI als auch CLI kompiliert und als sapi/cgi/php beziehungsweise sapi/cli/php in Ihrem PHP-Quellcodeverzeichnis hinterlegt. Sie werden bemerken, dass beide php heissen. Was während make install passiert, hängt von Ihrem configure-Kommando ab. Wenn ein Modul-SAPI während configure gewählt wird, wie etwa apxs oder wenn die --disable-cgi-Option benutzt wird, wird das CLI während make install nach {PREFIX}/bin/php kopiert, ansonsten wird das CGI dort hinterlegt. Also wird, wenn beispielsweise --with--apxs in Ihrem configure-Kommando auftaucht, das CLI während make install nach {PREFIX}/bin/php kopiert. Wenn Sie die Installation des CGI-Binaries außer Kraft setzen wollen, benutzen Sie make install-cli nach make install. Alternativ können Sie --disable-cgi in Ihrem configure-Kommando angeben.
Hinweis: Weil sowohl --enable-cli als auch --enable-cgi standardmäßig eingeschaltet sind, muss --enable-cli in Ihrem configure-Kommando nicht zwingend bedeuten, dass das CLI während make install nach {PREFIX}/bin/php kopiert wird.
Die Windows-Pakete zwischen PHP 4.2.0 und PHP 4.2.3 enthielten das CLI als php-cli.exe, beheimatet im selben Verzeichnis wie das CGI php.exe. Beginnend mit PHP 4.3.0 enthält das Windows-Paket das CLI als php.exe in einem eigenen Verzeichnis namens cli, also cli/php.exe. Beginnend mit PHP 5 wird das CLI im Hauptordner als php.exe ausgeliefert. Die CGI-Version heisst php-cgi.exe.
Seit PHP 5 gibt es eine neue Datei, php-win.exe. Diese ist identisch mit der CLI-Version, die einzige Ausnahme besteht darin, dass php-win nichts ausgibt und somit keine Konsole bietet. (Es erscheint keine "MS-DOS-Eingabeaufforderung".) Dieses Verhalten ist ähnlich php-gtk. Sie sollten die folgende Option für ./configure benutzen: --enable-cli-win32.
Hinweis: Welche SAPI habe ich? Auf der Kommandozeile wird Ihnen die Eingabe von php -v verraten, ob Sie php als CGI oder CLI einsetzen. Sehen Sie sich auch die Funktion php_sapi_name() und die Konstante PHP_SAPI an.
Hinweis: Eine UNIX manual page wurde in PHP 4.3.2 hinzugefügt. Sie können sie ansehen, indem sie man php auf der Kommandozeile eintippen.
Beachtenswerte Unterschiede des CLI SAPI verglichen mit anderen SAPIs:
-
Anders als beim CGI SAPI werden keine Header auf der Standardausgabe ausgegeben.
Obwohl das CGI SAPI einen Weg bietet, HTTP-Header zu unterdrücken, gibt es keine gleichwertige Option, sie im CLI SAPI anzuzeigen.
CLI wird standardmäßig im stillen Modus gestartet, dennoch gibt es die Optionen -q und --no-header aus Kompatibilitätsgründen noch, so dass Sie auch ältere CGI-Skripte noch benutzen können.
Es verändert das Arbeitsverzeichnis nicht zu dem des Skriptes. (Die Optionen -C und --no-chdir wurden aus Kompatibilitätsgründen beibehalten.)
Fehlermeldungen in Plaintext (keine HTML-Formatierung).
-
Es gibt bestimmte php.ini-Direktiven, die vom CLI SAPI außer Kraft gesetzt werden, weil sie in einer Kommandozeilenumgebung keinen Sinn ergeben.
Überschriebene php.ini-Direktiven Direktive CLI SAPI-Standardwert Kommentar html_errors FALSE Es kann sehr schwierig sein, eine Fehlermeldung auf der Kommandozeile zu lesen, wenn sie mit all diesen bedeutungslosen HTML-Tags vollgestopft ist, deswegen wird diese Direktive auf FALSE gesetzt. implicit_flush TRUE Es ist erwünscht, dass alle Ausgaben, die von print(), echo() und Konsorten kommen, sofort auf die Ausgabe geschrieben werden und nicht in irgendeinem Puffer gecacht werden. Sie können immer noch output buffering benutzen, wenn Sie die Standardausgabe aufschieben oder manipulieren wollen. max_execution_time 0 (unlimited) Wegen der unendlichen Möglichkeiten, PHP in Kommandozeilenumgebungen zu benutzen wurde die maximale Ausführungszeit auf unbegrenzte Zeit eingestellt. Wohingegen Anwendungen, die für das Web geschrieben wurden, oft in sehr kurzer Zeit ausgeführt werden, neigen Anwendungen für die Kommandozeile dazu, eine viel längere Ausführungszeit zu beanspruchen. register_argc_argv TRUE Weil diese Einstellung auf TRUE gesetzt ist, werden Sie immer Zugriff auf argc (Anzahl der Argumente, die der Anwendung übergeben wurden) und argv (Array der eigentlichen Argumente) im CLI SAPI haben.
Seit PHP 4.3.0 werden die PHP-Variablen $argc und $argv registriert und mit den entsprechenden Werten gefüllt, wenn das CLI SAPI benutzt wird. Vor dieser Version verhielt sich die Erzeugung dieser Variablen so wie in den CGI- und MODULE-Versionen, die die PHP-Direktive register_globals auf on verlangen. Ungeachtet der Version oder der Einstellung von register_globals können Sie immer $_SERVER oder $HTTP_SERVER_VARS benutzen. Beispiel: $_SERVER['argv']
Hinweis: Diese Direktiven können nicht mit einem anderen Wert aus der Konfigurationsdatei php.ini oder einer eigenen (falls angegeben) initialisiert werden. Das ist eine Einschränkung, weil diese Standardwerte angewandt werden, nachdem alle Konfigurationsdateien durchlaufen wurden. Dennoch können die Werte zur Laufzeit verändert werden (was aber für alle diese Direktiven keinen Sinn ergibt, beispielsweise register_argc_argv).
-
Um die Arbeit in der Kommandozeilenumgebung zu vereinfachen, wurden folgende Konstanten definiert:
CLI-spezifische Konstanten Konstante Beschreibung STDIN Ein schon geöffneter Stream auf stdin. Das erspart das Öffnen mit Wenn sie einzelne Zeilen von stdin lesen wollen, können Sie folgendes Code-Fragment benutzen:<?php
$stdin = fopen('php://stdin', 'r');
?><?php
$line = trim(fgets(STDIN)); // liest eine Zeile von STDIN
fscanf(STDIN, "%d\n", $number); // liest eine Zahl von STDIN
?>STDOUT Ein schon geöffneter Stream auf stdout. Das erspart das Öffnen mit <?php
$stdout = fopen('php://stdout', 'w');
?>STDERR Ein schon geöffneter Stream auf stderr. Das erspart das Öffnen mit <?php
$stderr = fopen('php://stderr', 'w');
?>Angesichts des oben genannten brauchen Sie beispielsweise nicht selbst einen Stream für stderr öffnen, sondern einfach die Konstante statt der Ressource benutzen:
Sie brauchen diese Ressourcen nicht explizit schliessen, weil sie automatisch von PHP geschlossen werden, wenn ihr Skript endet.php -r 'fwrite(STDERR, "stderr\n");'
Hinweis: Diese Konstanten sind nicht verfügbar wenn ein PHP Skript von stdin eingelesen wird.
-
Das CLI SAPI ändert das aktuelle Verzeichnis nicht auf das Verzeichnis des ausgeführten Skriptes!
Ein Beispiel, das den Unterschied zum CGI SAPI zeigt:
<?php
// Unsere einfache Anwendung namens test.php
echo getcwd(), "\n";
?>Bei der CGI-Version ist die Ausgabe folgende:
$ pwd /tmp $ php -q another_directory/test.php /tmp/another_directory
Dies zeigt deutlich, dass PHP das aktuelle Verzeichnis auf das des ausgeführten Skriptes ändert.
Benutzen der CLI SAPI-Version ergibt:
$ pwd /tmp $ php -f another_directory/test.php /tmp
Dies erlaubt eine größere Anpassungsfähigkeit beim Schreiben von Kommandozeilenanwendungen in PHP.
Hinweis: Das CGI SAPI unterstützt das Verhalten des CLI SAPI anhand der Option -C, wenn es auf der Kommandozeile gestartet wird.
Die Liste der Kommandozeilenoptionen, die das PHP-Binary bereitstellt, können jederzeit abgerufen werden, wenn man PHP mit der Option -h startet:
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...] php [options] -a -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 and execute <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 --ini Show configuration file names --rf <name> Show information about function <name>. --rc <name> Show information about class <name>. --re <name> Show information about extension <name>. --ri <name> Show configuration for extension <name>.
Beim CLI SAPI gibt es drei verschiedene Möglichkeiten, den zur Ausführung bestimmten PHP-Code zu übergeben:
-
PHP mitteilen, eine bestimmte Datei auszuführen.
php my_script.php php -f my_script.php
Beide Arten (ob sie die Option -f benutzen oder nicht) führen die Datei my_script.php aus. Sie können eine beliebige Datei ausführen - Ihr PHP-Skript muss nicht die Dateiendung .php haben, sie kann einen beliebigen Namen und eine beliebige Endung haben.
Hinweis: Wenn Sie Argumente an Ihr Skript übergeben wollen müssen Sie -- als erstes Argument übergeben wenn Sie die -f Option benutzen.
-
Den PHP-Code, der ausgeführt werden soll, direkt auf der Kommandozeile übergeben.
Bezüglich Ersetzung von Kommandozeilenvariablen und Benutzung von Quotes muss besondere Vorsicht getroffen werden.php -r 'print_r(get_defined_constants());'
Hinweis: Betrachten Sie das Beispiel sorgfältig, es sind keine Start- oder Endtags gesetzt! Die Option -r benötigt sie nicht. Werden sie dennoch verwendet, kommt es zu einem Parser-Fehler.
-
Stellen Sie den PHP-Code, der ausgeführt werden soll, über den Standard-Input (stdin) bereit.
Dies eröffnet die leistungsfähige Möglichkeit, PHP-Code dynamisch zu generieren und ihn dem PHP-Binary zu übergeben, wie in diesem möglichem Beispiel:
$ some_application | some_filter | php | sort -u >final_output.txt
Wie jede Kommandozeilenanwendung nimmt das PHP-Binary etliche Argumente entgegen, aber auch ein PHP-Skript kann Argumente entgegennehmen. Die Anzahl der Argumente, die an ein Skript übergeben werden können, ist nicht von PHP beschränkt (aber die Kommandozeilenumgebung hat ein bestimmtes Größenlimit für die Anzahl der Argumente, die übergeben werden können; normalerweise werden Sie dieses Limit nicht erreichen). Die Argumente, die dem Skript übergeben werden, sind in dem globalen Array $argv gespeichert. Der Null-Index enthält immer den Skriptnamen (das bedeutet -, wenn der PHP-Code entweder von der Standardeingabe oder von der Kommandozeilenoption -r kommt). Die zweite registrierte globale Variable ist $argc, die die Anzahl der Elemente im Array $argv enthält (nicht die Anzahl Argumente, die dem Skript übergeben wurden).
Solange die Argumente, die Sie dem Skript übergeben möchten, nicht mit dem Zeichen - beginnen, gibt es nichts besonderes zu beachten. Ein Argument, das mit - beginnt zu übergeben, wird Probleme bereiten, weil PHP selbst denkt, dass sie verarbeitet werden muss. Benutzen Sie das Argument-Trennzeichen -- um das zu vermeiden. Nachdem dieses Trennzeichen von PHP geparst wurde, wird jedes folgende Argument unangetastet an das Skript weitergereicht.
# Dies führt nicht den angegebenen Code aus, sondern die Optionen von PHP anzeigen $ php -r 'var_dump($argv);' -h Usage: php [options] [-f] <file> [args...] [...] # Dies übergibt das Argument '-h' an Ihr Skript und zeigt die Optionen von PHP nicht an $ php -r 'var_dump($argv);' -- -h array(2) { [0]=> string(1) "-" [1]=> string(2) "-h" }
Dennoch gibt es einen anderen Weg, um PHP für Kommandozeilenskripte zu benutzen. Sie können ein Skript erstellen, in dem die erste Zeile mit #!/usr/bin/php beginnt. Nachfolgend können Sie normalen PHP-Code innerhalb der PHP-Start- und -End-Tags setzen. Sobald Sie die Datei ausführbar gemacht haben (beispielsweise chmod +x test), kann Ihr Skript wie ein normales Kommandozeilen- oder Perl-Skript gestartet werden.
Beispiel #1 PHP als Shellskript ausführen
#!/usr/bin/php
<?php
var_dump($argv);
?>
Angenommen, die Datei heißt test und befindet sich im aktuellen Verzeichnis, dann können wir nun folgendes tun:
$ chmod 755 test $ ./test -h -- foo array(4) { [0]=> string(6) "./test" [1]=> string(2) "-h" [2]=> string(2) "--" [3]=> string(3) "foo" }
Wie Sie sehen können, müssen Sie sich in diesem Fall um nichts weiter kümmern, wenn Sie Ihrem Skript Paramater, die mit - beginnen, übergeben.
Die Langformen der Optionen sind seit PHP 4.3.3 verfügbar.
| Option | Langform | Beschreibung |
|---|---|---|
| -a | --interactive |
Startet PHP im interaktiven Modus. Wenn Sie PHP mit der Readline-Erweiterung (die unter Windows nicht verfügbar ist) kompilieren, bekommen Sie eine feine Shell, komplett mit einer Auto-Vervollständigung (das bedeutet, Sie können anfangen, einen Variablennamen zu tippen, die TAB-Taste drücken und PHP vervollständigt den Namen) und einem Verlauf der letzten Zeilen, auf den mit den Pfeiltasten zugegriffen werden kann. Der Verlauf wird in der Datei ~/.php_history gespeichert.
|
| -c | --php-ini |
Mit dieser Option kann man entweder ein Verzichnis angeben, wo nach php.ini gesucht werden soll, oder man kann eine eigene INI-Datei direkt angeben (diese muss nicht php.ini heissen). Zum Beispiel:
Wenn Sie diese Option nicht angeben, wird die Datei an den vorgegebenen Orten gesucht. |
| -n | --no-php-ini |
php.ini komplett ignorieren. Diese Option gibt es seit PHP 4.3.0. |
| -d | --define |
Diese Option erlaubt es Ihnen, einen eigenen Wert für eine beliebige in php.ini erlaubte Direktive zu setzen. Die Syntax ist:
Beispiele (die Zeilen sind aus layouttechnischen Gründen umgebrochen):
|
| -e | --profile-info |
Erweiterte Informationen für Debugger/Profiler erstellen. |
| -f | --file |
Parst und führt die angegebene Datei aus. Diese Option ist nicht verbindlich und kann weggelassen werden. Alleinige Angabe des Dateinamens ist ausreichend.
|
| -h und -? | --help und --usage | Mit dieser Option bekommen Sie Informationen über die tatsächlichen Kommandozeilenoptionen und kurze Beschreibungen dazu. |
| -i | --info | Diese Kommandozeilenoption ruft phpinfo() auf und gibt das Ergebnis aus. Wenn PHP nicht korrekt funktioniert, ist es ratsam, php -i zu benutzen und nachzusehen, ob etwa Fehlermeldungen vor oder statt der Informationstabellen ausgegeben werden. Beachten Sie, dass die Ausgabe bei Verwendung des CGI-Modus in HTML erfolgt und deswegen ziemlich umfangreich ist. |
| -l | --syntax-check |
Diese Option stellt eine angenehme Methode bereit, nur eine Syntaxüberprüfung auf den angegebenen PHP-Code durchzuführen. Bei Erfolg wird der Text No syntax errors detected in <filename> auf die Standardausgabe geschrieben und der Rückgabewert ist 0. Bei Misserfolg wird der Text Errors parsing <filename> zusätzlich zur internen Parser-Fehlermeldung auf der Standardausgabe ausgegeben und der Rückgabewert auf 255 gesetzt. Diese Option wird keine Fatalen Fehler (wie undefinierte Funktionen) finden. Benutzen Sie die Option -f, wenn sie auch diese überprüfen wollen.
|
| -m | --modules |
Wird diese Option benutzt, gibt PHP die eingebauten (und geladenen) PHP- und Zend-Module aus:
|
| -r | --run |
Diese Option erlaubt die Ausführung von PHP direkt aus der Kommandozeile. Die PHP-Start- und -End-Tags (<?php und ?>) werden nicht benötigt und verursachen Parserfehler, wenn sie dennoch vorhanden sind.
|
| -B | --process-begin |
PHP-Code der ausgeführt werden soll, bevor stdin ausgewertet wird. Verfügbar seit PHP 5. |
| -R | --process-code |
PHP-Code der für jede Eingabezeile ausgeführt werden soll. Verfügbar seit PHP 5. Es gibt zwei spezielle Variablen in diesem Modus: $argn und $argi. $argn enthält die Zeile, die PHP gerade verarbeitet und $argi enthält die Zeilennummer. |
| -F | --process-file |
PHP-Datei die für jede Eingabezeile ausgeführt werden soll. Verfügbar seit PHP 5. |
| -E | --process-end |
PHP-Code der nach der Verarbeitung der Eingabe ausgeführt werden soll. Verfügbar seit PHP 5. Ein Beispiel, wie man die Optionen -B, -R und -E benutzt, um die Anzahl der Zeilen in einem Projekt zu zählen.
|
| -s | --syntax-highlight and --syntax-highlighting |
Den Quelltext mit farbiger Syntaxhervorhebung anzeigen. Diese Option benutzt den internen Mechanismus zum Analysieren der Datei, generiert eine HTML-Version mit Syntax-Highlighting davon, und schreibt sie auf die Standardausgabe. Beachten Sie, dass sie nur einen Block von <code> [...] </code>-HTML-Tags erzeugt, keine HTML-Header.
|
| -v | --version |
Schreibt die Version von PHP, PHP SAPI und Zend auf die Standardausgabe. Zum Beispiel:
|
| -w | --strip |
Den Quelltext mit entfernten Kommentaren und Leerzeichen anzeigen.
|
| -z | --zend-extension |
Eine Zend-Erweiterung laden. Wenn nur ein Dateiname angegeben wird, versucht PHP, die Erweiterung aus dem momentanen Standard-Bibliotheken-Pfad auf Ihrem System zu laden (auf Linux-Systemen normalerweise in /etc/ld.so.conf angegeben). Wenn ein Dateiname mit absoluter Pfadinformation übergeben wird, wird der Bibliotheken-Pfad des Systems nicht benutzt. Ein relativer Dateiname mit Pfadinformationen wird PHP nur veranlassen, zu versuchen, die Erweiterung in einem Pfad relativ zum aktuellen Verzeichnis zu laden. |
| --ini |
Zeigt die Namen der Konfigurationsdateien und die durchsuchten Verzeichnisse. Verfügbar seit PHP 5.2.3. Beispiel #2 --ini example $ php --ini Configuration File (php.ini) Path: /usr/dev/php/5.2/lib Loaded Configuration File: /usr/dev/php/5.2/lib/php.ini Scan for additional .ini files in: (none) additional .ini files parsed: (none) |
|
| --rf | --rfunction |
Zeigt Informationen über die gegebene Funktion oder Klassenmethode (z.B. Anzahl und Name der Parameter). Verfügbar seit PHP 5.1.2. Diese Option ist nur verfügbar wenn PHP mit Reflection Unterstützung kompiliert wurde.
Beispiel #3 Einfache --rf Nutzung
$ php --rf var_dump
Function [ <internal> public function var_dump ] {
- Parameters [2] {
Parameter #0 [ <required> $var ]
Parameter #1 [ <optional> $... ]
}
}
|
| --rc | --rclass |
Zeigt Inforationen über die gegebene Klasse (Liste der Konstanten, Eigenschaften und Methoden). Verfügbar seit PHP 5.1.2. Diese Option ist nur verfügbar wenn PHP mit Reflection Unterstützung kompiliert wurde.
Beispiel #4 --rc example
$ php --rc Directory
Class [ <internal:standard> class Directory ] {
- Constants [0] {
}
- Static properties [0] {
}
- Static methods [0] {
}
- Properties [0] {
}
- Methods [3] {
Method [ <internal> public method close ] {
}
Method [ <internal> public method rewind ] {
}
Method [ <internal> public method read ] {
}
}
}
|
| --re | --rextension |
Zeigt Informationen über die gegebene Extension (Liste der php.ini Optionen, definierte Funktionen, Konstanten und Klassen. Verfügbar seit PHP 5.1.2. Diese Option ist nur verfügbar wenn PHP mit Reflection Unterstützung kompiliert wurde.
Beispiel #5 --re example
$ php --re json
Extension [ <persistent> extension #19 json version 1.2.1 ] {
- Functions {
Function [ <internal> function json_encode ] {
}
Function [ <internal> function json_decode ] {
}
}
}
|
| --ri | --rextinfo |
Zeigt die Konfiguration der gegebenen Extension (entspricht der von phpinfo() zurückgegebenen Information). Verfügbar seit PHP 5.2.2. Die Konfiguration des Sprachkerns können über den speziellen Extension Namen "main" ermittelt werden.
Beispiel #6 --ri example $ php --ri date date date/time support => enabled "Olson" Timezone Database Version => 2007.5 Timezone Database => internal Default timezone => Europe/Oslo Directive => Local Value => Master Value date.timezone => Europe/Oslo => Europe/Oslo date.default_latitude => 59.22482 => 59.22482 date.default_longitude => 11.018084 => 11.018084 date.sunset_zenith => 90.583333 => 90.583333 date.sunrise_zenith => 90.583333 => 90.583333 |
Die ausführbare PHP-Version kann benutzt werden, um PHP-Skripte vollkommen unabhängig von einem Webserver auszuführen. Wenn Sie auf einem UNIX-System arbeiten, sollten Sie Ihrem Skript eine spezielle erste Zeile hinzufügen und es ausführbar machen, so dass das System erkennt, welches Programm das Skript ausführen soll. Auf einem Windows-System können Sie php.exe mit der Doppelklick-Option von .php-Dateien verknüpfen. Sie können auch eine Batchdatei erzeugen, um das Skript von PHP ausführen zu lassen. Die erste Zeile, die dem Skript hinzugefügt wird, damit es unter UNIX läuft, stört unter Windows nicht, so dass Sie auf diese Weise problemlos plattformübergreifende Programme schreiben können. Sie finden anschließend ein einfaches Beispiel, wie man ein Kommandozeilenprogramm in PHP schreibt.
Beispiel #7 Ein Skript, das von der Kommandozeile aus ausgeführt werden soll (script.php)
#!/usr/bin/php
<?php
if ($argc != 2 || in_array($argv[1], array('--help', '-help', '-h', '-?'))) {
?>
Das ist ein Kommandozeilenprogramm in PHP mit einer Option.
benutzung:
<?php echo $argv[0]; ?> <option>
<option> kann ein Wort sein, das Sie gerne
ausgeben möchten. Mit den Optionen --help,
-help, -h oder -? bekommen Sie diese Hilfe.
<?php
} else {
echo $argv[1];
}
?>
In dem oben beschriebenen Skript haben wir die erste Zeile dazu benutzt anzugeben, dass die Datei von PHP ausgeführt werden soll. Wir arbeiten hier mit einer CLI-version, deswegen werden keine HTTP-Header ausgegeben. Es gibt zwei Variablen, die Sie in Kommandozeilen-Applikationen mit PHP benutzen können: $argc und $argv. Die erste ist die Anzahl der Argumente plus Eins (dem Namen des laufenden Skripts). Die zweite ist ein Array, das die Argumente enthält, beginnend mit dem Skriptnamen als Nummer Null ($argv[0]).
In dem oben genannten Programm haben wir überprüft, ob es weniger oder mehr als zwei Argumente gibt. Falls das Argument --help, -help, -h oder -? war, haben wir die Hilfe-Nachricht mit dem dynamisch übergebenen Skriptnamen ausgegeben. Wenn wir ein anderes Argument erhalten haben, haben wir es ausgegeben.
Wenn Sie das oben genannte Skript unter UNIX laufen lassen wollen, müssen Sie es zuerst ausführbar machen, und es danach einfach als script.php echothis oder script.php -h aufrufen. Unter Windows können Sie zu diesem Zweck eine Batchdatei erstellen:
Beispiel #8 Batchdatei zur Ausführung eines Kommandozeilen-Skripts in PHP (script.bat)
@C:\php\php.exe script.php %1 %2 %3 %4
Angenommen, Sie haben das Programm script.php genannt und die CLI-php.exe hat den Pfad c:\php\php.exe, wird diese Batchdatei es mit den von Ihnen übergebnen Optionen ausführen: script.bat echothis oder script.bat -h.
Sehen Sie sich auch die zusätzlichen Funktionen in der Dokumentation der Readline-Extension an, um Ihre in PHP geschriebenen Kommandozeilenanwendungen zu verbessern.
PHP auf der Kommandozeile
07-May-2008 01:08
29-Feb-2008 06:32
When you want to get inputs from STDIN, you may use this function if you like using C coding style.
<?php
// up to 8 variables
function scanf($format, &$a0=NULL, &$a1=NULL, &$a2=NULL, &$a3=NULL,
&$a4=NULL, &$a5=NULL, &$a6=NULL, &$a7=NULL)
{
$num_args = func_num_args();
if($num_args > 1) {
$inputs = fscanf(STDIN, $format);
for($i=0; $i<$num_args-1; $i++) {
$arg = 'a'.$i;
$$arg = $inputs[$i];
}
}
}
scanf("%d", $number);
?>
16-Feb-2008 09:29
I find regex and manually breaking up the arguments instead of havingon $_SERVER['argv'] to do it more flexiable this way.
cli_test.php asdf asdf --help --dest=/var/ -asd -h --option mew arf moo -z
Array
(
[input] => Array
(
[0] => asdf
[1] => asdf
)
[commands] => Array
(
[help] => 1
[dest] => /var/
[option] => mew arf moo
)
[flags] => Array
(
[0] => asd
[1] => h
[2] => z
)
)
<?php
function arguments ( $args )
{
array_shift( $args );
$args = join( $args, ' ' );
preg_match_all('/ (--\w+ (?:[= ] [^-]+ [^\s-] )? ) | (-\w+) | (\w+) /x', $args, $match );
$args = array_shift( $match );
/*
Array
(
[0] => asdf
[1] => asdf
[2] => --help
[3] => --dest=/var/
[4] => -asd
[5] => -h
[6] => --option mew arf moo
[7] => -z
)
*/
$ret = array(
'input' => array(),
'commands' => array(),
'flags' => array()
);
foreach ( $args as $arg ) {
// Is it a command? (prefixed with --)
if ( substr( $arg, 0, 2 ) === '--' ) {
$value = preg_split( '/[= ]/', $arg, 2 );
$com = substr( array_shift($value), 2 );
$value = join($value);
$ret['commands'][$com] = !empty($value) ? $value : true;
continue;
}
// Is it a flag? (prefixed with -)
if ( substr( $arg, 0, 1 ) === '-' ) {
$ret['flags'][] = substr( $arg, 1 );
continue;
}
$ret['input'][] = $arg;
continue;
}
return $ret;
}
print_r( arguments( $argv ) );
?>
12-Feb-2008 06:21
Here's an update to the script a couple of people gave below to read arguments from $argv of the form --name=VALUE and -flag. Changes include:
Don't use $_ARG - $_ is generally considered reserved for the engine.
Don't use regex where a string operation will do just as nicely
Don't overwrite --name=VALUE with -flag when 'name' and 'flag' are the same thing
Allow for VALUE that has an equals sign in it
function arguments($argv) {
$ARG = array();
foreach ($argv as $arg) {
if (strpos($arg, '--') === 0) {
$compspec = explode('=', $arg);
$key = str_replace('--', '', array_shift($compspec));
$value = join('=', $compspec);
$ARG[$key] = $value;
} elseif (strpos($arg, '-') === 0) {
$key = str_replace('-', '', $arg);
if (!isset($ARG[$key])) $ARG[$key] = true;
}
}
return $ARG;
}
28-Oct-2007 04:51
Here's <losbrutos at free dot fr> function modified to support unix like param syntax like <B Crawford> mentions:
<?php
function arguments($argv) {
$_ARG = array();
foreach ($argv as $arg) {
if (preg_match('#^-{1,2}([a-zA-Z0-9]*)=?(.*)$#', $arg, $matches)) {
$key = $matches[1];
switch ($matches[2]) {
case '':
case 'true':
$arg = true;
break;
case 'false':
$arg = false;
break;
default:
$arg = $matches[2];
}
/* make unix like -afd == -a -f -d */
if(preg_match("/^-([a-zA-Z0-9]+)/", $matches[0], $match)) {
$string = $match[1];
for($i=0; strlen($string) > $i; $i++) {
$_ARG[$string[$i]] = true;
}
} else {
$_ARG[$key] = $arg;
}
} else {
$_ARG['input'][] = $arg;
}
}
return $_ARG;
}
?>
Sample:
eromero@ditto ~/workspace/snipplets $ foxogg2mp3.php asdf asdf --help --dest=/var/ -asd -h
Array
(
[input] => Array
(
[0] => /usr/local/bin/foxogg2mp3.php
[1] => asdf
[2] => asdf
)
[help] => 1
[dest] => /var/
[a] => 1
[s] => 1
[d] => 1
[h] => 1
)
22-Oct-2007 02:11
I was looking for a way to interactively get a single character response from user. Using STDIN with fread, fgets and such will only work after pressing enter. So I came up with this instead:
#!/usr/bin/php -q
<?php
function inKey($vals) {
$inKey = "";
While(!in_array($inKey,$vals)) {
$inKey = trim(`read -s -n1 valu;echo \$valu`);
}
return $inKey;
}
function echoAT($Row,$Col,$prompt="") {
// Display prompt at specific screen coords
echo "\033[".$Row.";".$Col."H".$prompt;
}
// Display prompt at position 10,10
echoAT(10,10,"Opt : ");
// Define acceptable responses
$options = array("1","2","3","4","X");
// Get user response
$key = inKey($options);
// Display user response & exit
echoAT(12,10,"Pressed : $key\n");
?>
Hope this helps someone.
21-Oct-2007 07:01
I have not seen in this thread any code snippets that support the full *nix style argument parsing. Consider this:
<?php
print_r(getArgs($_SERVER['argv']));
function getArgs($args) {
$out = array();
$last_arg = null;
for($i = 1, $il = sizeof($args); $i < $il; $i++) {
if( (bool)preg_match("/^--(.+)/", $args[$i], $match) ) {
$parts = explode("=", $match[1]);
$key = preg_replace("/[^a-z0-9]+/", "", $parts[0]);
if(isset($parts[1])) {
$out[$key] = $parts[1];
}
else {
$out[$key] = true;
}
$last_arg = $key;
}
else if( (bool)preg_match("/^-([a-zA-Z0-9]+)/", $args[$i], $match) ) {
for( $j = 0, $jl = strlen($match[1]); $j < $jl; $j++ ) {
$key = $match[1]{$j};
$out[$key] = true;
}
$last_arg = $key;
}
else if($last_arg !== null) {
$out[$last_arg] = $args[$i];
}
}
return $out;
}
/*
php file.php --foo=bar -abc -AB 'hello world' --baz
produces:
Array
(
[foo] => bar
[a] => true
[b] => true
[c] => true
[A] => true
[B] => hello world
[baz] => true
)
*/
?>
27-Sep-2007 05:54
an another "another variant" :
<?php
function arguments($argv)
{
$_ARG = array();
foreach ($argv as $arg)
{
if (preg_match('#^-{1,2}([a-zA-Z0-9]*)=?(.*)$#', $arg, $matches))
{
$key = $matches[1];
switch ($matches[2])
{
case '':
case 'true':
$arg = true;
break;
case 'false':
$arg = false;
break;
default:
$arg = $matches[2];
}
$_ARG[$key] = $arg;
}
else
{
$_ARG['input'][] = $arg;
}
}
return $_ARG;
}
?>
$php myscript.php arg1 -arg2=val2 --arg3=arg3 -arg4 --arg5 -arg6=false
Array
(
[input] => Array
(
[0] => myscript.php
[1] => arg1
)
[arg2] => val2
[arg3] => arg3
[arg4] => true
[arg5] => true
[arg5] => false
)
16-Aug-2007 12:24
For those who was unable to clear the windows screen trying to run CLS command:
CLS is not an windows executable file! It is an option from command.com!
So, the rigth command is
system("command /C cls");
22-Jul-2007 11:04
Just another variant of previous script that group arguments doesn't starts with '-' or '--'
function arguments($argv) {
$_ARG = array();
foreach ($argv as $arg) {
if (ereg('--([^=]+)=(.*)',$arg,$reg)) {
$_ARG[$reg[1]] = $reg[2];
} elseif(ereg('^-([a-zA-Z0-9])',$arg,$reg)) {
$_ARG[$reg[1]] = 'true';
} else {
$_ARG['input'][]=$arg;
}
}
return $_ARG;
}
$ php myscript.php --user=nobody /etc/apache2/*
Array
(
[input] => Array
(
[0] => myscript.php
[1] => /etc/apache2/apache2.conf
[2] => /etc/apache2/conf.d
[3] => /etc/apache2/envvars
[4] => /etc/apache2/httpd.conf
[5] => /etc/apache2/mods-available
[6] => /etc/apache2/mods-enabled
[7] => /etc/apache2/ports.conf
[8] => /etc/apache2/sites-available
[9] => /etc/apache2/sites-enabled
)
[user] => nobody
)
25-Jun-2007 11:02
In 5.1.2 (and others, I assume), the -f form silently drops the first argument after the script name from $_SERVER['argv']. I'd suggest avoiding it unless you need it for a special case.
04-Jun-2007 05:16
Just a variant of previous script to accept arguments with '=' also
<?php
function arguments($argv) {
$_ARG = array();
foreach ($argv as $arg) {
if (ereg('--([^=]+)=(.*)',$arg,$reg)) {
$_ARG[$reg[1]] = $reg[2];
} elseif(ereg('-([a-zA-Z0-9])',$arg,$reg)) {
$_ARG[$reg[1]] = 'true';
}
}
return $_ARG;
}
?>
$ php myscript.php --user=nobody --password=secret -p --access="host=127.0.0.1 port=456"
Array
(
[user] => nobody
[password] => secret
[p] => true
[access] => host=127.0.0.1 port=456
)
12-May-2007 02:55
While working with command line scripts it is tedious to handle the arguments in a numerated array.
The following code will:
If the argument is of the form –NAME=VALUE it will be represented in the array as an element with the key NAME and the value VALUE. I the argument is a flag of the form -NAME it will be represented as a boolean with the name NAME with a value of true in the associative array.
<?php
function arguments($argv) {
$_ARG = array();
foreach ($argv as $arg) {
if (ereg('--[a-zA-Z0-9]*=.*',$arg)) {
$str = split("=",$arg); $arg = '';
$key = ereg_replace("--",'',$str[0]);
for ( $i = 1; $i < count($str); $i++ ) {
$arg .= $str[$i];
}
$_ARG[$key] = $arg;
} elseif(ereg('-[a-zA-Z0-9]',$arg)) {
$arg = ereg_replace("-",'',$arg);
$_ARG[$arg] = 'true';
}
}
return $_ARG;
}
?>
Example:
<?php print_r(arguments($argv)); ?>
# php5 myscript.php --user=nobody --password=secret -p
Array
(
[user] => nobody
[password] => secret
[p] => true
)
08-Apr-2007 03:27
I had a problem with PHP 5.2.0 (cli) (winXP) that no output was printed when I tried to run any file. Using the -n switch solved the problem.
Apparently the interpreter can't always find php.ini, even though both exist in the same folder and the PATH variable is set correctly. No error messages were printed either.
23-Mar-2007 12:48
i use emacs in c-mode for editing. in 4.3, starting a cli script like so:
#!/usr/bin/php -q /* -*- c -*- */
<?php
told emacs to drop into c-mode automatically when i loaded the file for editing. the '-q' flag didn't actually do anything (in the older cgi versions, it suppressed html output when the script was run) but it caused the commented mode line to be ignored by php.
in 5.2, '-q' has apparently been deprecated. replace it with '--' to achieve the 4.3 invocation-with-emacs-mode-line behavior:
#!/usr/bin/php -- /* -*- c -*- */
<?php
don't go back to your 4.3 system and replace '-q' with '--'; it seems to cause php to hang waiting on STDIN...
09-Mar-2007 07:14
To display colored text when it is actually supported :
<?php
echo "\033[31m".$myvar; // red foreground
echo "\033[41m".$myvar; // red background
?>
To reset these settings :
<?php
echo "\033[0m";
?>
More fun :
<?php
echo "\033[5;30m;\033[48mWARNING !"; // black blinking text over red background
?>
More info here : http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x329.html
05-Mar-2007 08:03
python coders might miss this construct when working in PHP:
if __name__=='__main__':
# handle direct invocation from command line
it's a great way to embed little bits of test code (or a full-on cli for that matter),
while keeping the source file usable in other contexts.
Far as I can tell, this is the closest approximation available in PHP5:
if ('cli'===php_sapi_name() &&
__FILE__===realpath(
getcwd().DIRECTORY_SEPARATOR.$_SERVER['argv'][0]
)) {
// handle direct invocation from command line
}
26-Nov-2006 08:46
Hi,
This function clears the screen, like "clear screen"
<?php
function clearscreen($out = TRUE) {
$clearscreen = chr(27)."[H".chr(27)."[2J";
if ($out) print $clearscreen;
else return $clearscreen;
}
?>
14-Nov-2006 12:57
An addition to my previous post (you can replace it)
If your php script doesn't run with shebang (#!/usr/bin/php),
and it issues the beautifull and informative error message:
"Command not found." just dos2unix yourscript.php
et voila.
If you still get the "Command not found."
Just try to run it as ./myscript.php , with the "./"
if it works - it means your current directory is not in the executable search path.
If your php script doesn't run with shebang (#/usr/bin/php),
and it issues the beautifull and informative message:
"Invalid null command." it's probably because the "!" is missing in the the shebang line (like what's above) or something else in that area.
\Alon
It seems like 'max_execution_time' doesn't work on CLI.
<?php
php -d max_execution_time=20
-r '$foo = ini_get("max_execution_time"); var_dump($foo);'
?>
will print string(2) "20", but if you'l run infinity while: while(true) for example, it wouldn't stop after 20 seconds.
Testes on Linux Gentoo, PHP 5.1.6.
15-Sep-2006 03:59
On windows, you can simulate a cls by echoing out just \r. This will keep the cursor on the same line and overwrite what was on the line.
for example:
<?php
echo "Starting Iteration" . "\n\r";
for ($i=0;$i<10000;$i++) {
echo "\r" . $i;
}
echo "Ending Iteration" . "\n\r";
?>
21-Aug-2006 12:20
If your php script doesn't run with shebang (#!/usr/bin/php),
and it issues the beautifull and informative error message:
"Command not found." just dos2unix yourscript.php
et voila.
If your php script doesn't run with shebang (#/usr/bin/php),
and it issues the beautifull and informative message:
"Invalid null command." it's probably because the "!" is missing in the the shebang line (like what's above) or something else in that area.
\Alon
21-Feb-2006 10:27
Spawning php-win.exe as a child process to handle scripting in Windows applications has a few quirks (all having to do with pipes between Windows apps and console apps).
To do this in C++:
// We will run php.exe as a child process after creating
// two pipes and attaching them to stdin and stdout
// of the child process
// Define sa struct such that child inherits our handles
SECURITY_ATTRIBUTES sa = { sizeof(SECURITY_ATTRIBUTES) };
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
// Create the handles for our two pipes (two handles per pipe, one for each end)
// We will have one pipe for stdin, and one for stdout, each with a READ and WRITE end
HANDLE hStdoutRd, hStdoutWr, hStdinRd, hStdinWr;
// Now create the pipes, and make them inheritable
CreatePipe (&hStdoutRd, &hStdoutWr, &sa, 0))
SetHandleInformation(hStdoutRd, HANDLE_FLAG_INHERIT, 0);
CreatePipe (&hStdinRd, &hStdinWr, &sa, 0)
SetHandleInformation(hStdinWr, HANDLE_FLAG_INHERIT, 0);
// Now we have two pipes, we can create the process
// First, fill out the usage structs
STARTUPINFO si = { sizeof(STARTUPINFO) };
PROCESS_INFORMATION pi;
si.dwFlags = STARTF_USESTDHANDLES;
si.hStdOutput = hStdoutWr;
si.hStdInput = hStdinRd;
// And finally, create the process
CreateProcess (NULL, "c:\\php\\php-win.exe", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi);
// Close the handles we aren't using
CloseHandle(hStdoutWr);
CloseHandle(hStdinRd);
// Now that we have the process running, we can start pushing PHP at it
WriteFile(hStdinWr, "<?php echo 'test'; ?>", 9, &dwWritten, NULL);
// When we're done writing to stdin, we close that pipe
CloseHandle(hStdinWr);
// Reading from stdout is only slightly more complicated
int i;
std::string processed("");
char buf[128];
while ( (ReadFile(hStdoutRd, buf, 128, &dwRead, NULL) && (dwRead != 0)) ) {
for (i = 0; i < dwRead; i++)
processed += buf[i];
}
// Done reading, so close this handle too
CloseHandle(hStdoutRd);
A full implementation (implemented as a C++ class) is available at http://www.stromcode.com
25-Sep-2005 12:08
When you're writing one line php scripts remember that 'php://stdin' is your friend. Here's a simple program I use to format PHP code for inclusion on my blog:
UNIX:
cat test.php | php -r "print htmlentities(file_get_contents('php://stdin'));"
DOS/Windows:
type test.php | php -r "print htmlentities(file_get_contents('php://stdin'));"
19-Sep-2005 12:27
I needed this, you proly wont tho.
puts the exicution args into $_GET
<?php
if ($argv) {
foreach ($argv as $k=>$v)
{
if ($k==0) continue;
$it = explode("=",$argv[$i]);
if (isset($it[1])) $_GET[$it[0]] = $it[1];
}
}
?>
16-Sep-2005 09:06
To pass more than 9 arguments to your php-script on Windows, you can use the 'shift'-command in a batch file. After using 'shift', %1 becomes %0, %2 becomes %1 and so on - so you can fetch argument 10 etc.
Here's an example - hopefully ready-to-use - batch file:
foo.bat:
---------
@echo off
:init_arg
set args=
:get_arg
shift
if "%0"=="" goto :finish_arg
set args=%args% %0
goto :get_arg
:finish_arg
set php=C:\path\to\php.exe
set ini=C:\path\to\php.ini
%php% -c %ini% foo.php %args%
---------
Usage on commandline:
foo -1 -2 -3 -4 -5 -6 -7 -8 -9 -foo -bar
A print_r($argv) will give you all of the passed arguments.
18-Aug-2005 01:53
Hi, parsing the commandline (argv) can be very simple in PHP.
If you use keyword parms like:
script.php parm1=value parm3=value
All you have to do in script.php is:
for ($i=1; $i < $argc; $i++) {parse_str($argv[$i]);}
$startup=compact('parm1', 'parm2', 'parm3');
14-Jul-2005 05:44
dunno if this is on linux the same but on windows evertime
you send somthing to the console screen php is waiting for
the console to return. therefor if you send a lot of small
short amounts of text, the console is starting to be using
more cpu-cycles then php and thus slowing the script.
take a look at this sheme:
cpu-cycle:1 ->php: print("a");
cpu-cycle:2 ->cmd: output("a");
cpu-cycle:3 ->php: print("b");
cpu-cycle:4 ->cmd: output("b");
cpu-cycle:5 ->php: print("c");
cpu-cycle:6 ->cmd: output("c");
cpu-cylce:7 ->php: print("d");
cpu-cycle:8 ->cmd: output("d");
cpu-cylce:9 ->php: print("e");
cpu-cycle:0 ->cmd: output("e");
on the screen just appears "abcde". but if you write
your script this way it will be far more faster:
cpu-cycle:1 ->php: ob_start();
cpu-cycle:2 ->php: print("abc");
cpu-cycle:3 ->php: print("de");
cpu-cycle:4 ->php: $data = ob_get_contents();
cpu-cycle:5 ->php: ob_end_clean();
cpu-cycle:6 ->php: print($data);
cpu-cycle:7 ->cmd: output("abcde");
now this is just a small example but if you are writing an
app that is outputting a lot to the console, i.e. a text
based screen with frequent updates, then its much better
to first cach all output, and output is as one big chunk of
text instead of one char a the time.
ouput buffering is ideal for this. in my script i outputted
almost 4000chars of info and just by caching it first, it
speeded up by almost 400% and dropped cpu-usage.
because what is being displayed doesn't matter, be it 2
chars or 40.0000 chars, just the call to output takes a
great deal of time. remeber that.
maybe someone can test if this is the same on unix-based
systems. it seems that the STDOUT stream just waits for
the console to report ready, before continueing execution.
24-Jun-2005 08:07
For windows clearing the screen using "system('cls');" does not work (at least for me)...
Although this is not pretty it works... Simply send 24 newlines after the output (for one line of output, 23 for two, etc
Here is a sample function and usage:
function CLS($lines){ // $lines = number of lines of output to keep
for($i=24;$i>=$lines;$i--) @$return.="\n";
return $return;
}
fwrite(STDOUT,"Still Processing: Total Time ".$i." Minutes so far..." . CLS(1));
Hope This Helps,
Wallacebw
30-May-2005 07:32
If you are using Windows XP (I think this works on 2000, too) and you want to be able to right-click a .php file and run it from the command line, follow these steps:
1. Run regedit.exe and *back up the registry.*
2. Open HKEY_CLASSES_ROOT and find the ".php" key.
IF IT EXISTS:
------------------
