PHP op de commandline
Buiten dat je PHP als webdevelopment taal kunt gebruiken, kun je PHP ook aardig gebruiken voor dingen op de commandline. Dit kan zowel op Windows als op Linux, al biedt de standaard Linux shell meer mogelijkheden dan de standaard Windows shell. We kijken eens naar wat PHP ons zoal kan bieden.
PHP code uitvoeren vanaf de commandline
Eerder had ik het al over de interactieve shell die PHP ook biedt. Met het -r argument kun je echter ook direct vanaf de commandline een stukje PHP code uitvoeren. Dit is handig als je even iets wilt testen:
-
$ php -r 'echo "Hallo, wereld!";'
-
Hallo, wereld
Let op: deze optie is alleen beschikbaar als PHP als CLI binary gebruikt wordt.
Wat nog leuker is, en dit is een geinig trucje dat ze waarschijnlijk hebben afgekeken van AWK, een tool die al sinds jaar en dag op deze manier gebruikt wordt, is het schrijven van code die aan het begin, in het midden, en aan het eind van een pipe gebruikt kan worden.
Kortom, als je PHP in een pipe constructie gebruikt, kun je code uitvoeren op het moment dat de pipe gemaakt wordt, op het moment dat er gegevens door de pipe vloeien en op het moment dat alle data langs is geweest. Dit kan er dan zo uitzien:
-
$ ls | php -R 'echo "Ik ontving een bestand: $argn\n";
-
Ik ontving een bestand: part1.txt
-
Ik ontving een bestand: voorbeeld1.php
-
Ik ontving een bestand: voorbeeld2.php
Met het -R argument definieer je een stuk code dat je voor elke regel data die door de pipe komt wilt uitvoeren. De regel die binnenkomt vind je in de variable $argn. Er zijn nog twee andere argumenten die je kunt gebruiken, en dat zijn -B: code die je aan het begin wilt uitvoeren, en -E: code die je aan het eind van de pipe wilt uitvoeren. Een iets completer voorbeeld met een lange regel:
-
$ ls | php -B '$numPhp = 0;' -R 'if (preg_match("~\.php$~i",$argn)) $numPhp++; ' -E 'echo "Aantal PHP files: $numPhp\n";'
-
Aantal PHP files: 2
Let op: deze optie is alleen beschikbaar als PHP als CLI binary gebruikt wordt.
Dit script ontvangt gegevens van ls en controleert op elke regel of deze eindigt op .php. Zoja, dan wordt er een variabele opgehoogd. Aan het eind van de pipe geven we weer hoeveel PHP-bestanden we hebben gevonden.
Think larger
De bovenstaande voorbeelden zijn natuurlijk alleen bruikbaar als je relatief kleine scripts nodig hebt. Anders loopt het al gauw uit de hand met enorme commandlines die bijzonder lastig zijn om te wijzigen. Gelukkig kun je ook vanuit een "gewoon" script met de shell bezig zijn:
-
$ ls | php voorbeeld1.php
-
Ik ontving een bestand: part1.txt
-
Ik ontving een bestand: voorbeeld1.php
-
Ik ontving een bestand: voorbeeld2.php
STDIN is een van de constanten die PHP definieert voor standaard IO streams. Zoals je ziet kun je deze gewoon gebruiken alsof het een resource is die je normaal van de fopen() functie terug krijgt. Er zijn in totaal 3 constanten:
- STDIN: read-only toegang tot inkomende data
- STDOUT: schrijf toegang tot de standaard output.
- STDERR: schrijf toegang tot de "fouten" output stream. Dit kun je gebruiken om foutmeldingen apart van je normale output te tonen.
Je kunt op de commandline ook de output op STDOUT en STDERR scheiden door gebruik te maken van redirection:
Zonder redirection:
-
$ ls | php voorbeeld1.php
-
Ik ontving een bestand: part1.txt
-
Ik ontving een bestand: voorbeeld1.php
-
Ik ontving een bestand: voorbeeld2.php
-
Er ging iets niet goed!
Vervolgens willen we alleen de foutmelding in een log file hebben:
-
$ ls | php voorbeeld1.php 2>error.log
-
Ik ontving een bestand: part1.txt
-
Ik ontving een bestand: voorbeeld1.php
-
Ik ontving een bestand: voorbeeld2.php
-
$ cat error.log
-
Er ging iets niet goed!
What's your argument, sir?
Het kan natuurlijk zijn dat je argumenten wilt kunnen ontvangen in je PHP script. Deze argumenten kun je benaderen via de variabele $argv. Dit is een array met alle meegegeven argumenten. In de variabele $argc vind je het aantal argumenten dat wordt meegegeven. Het eerste element is altijd het script dat wordt uitgevoerd, alle andere elementen zijn opgegeven argumenten:
-
$ php voorbeeld3.php http://www.scriptorama.nl http://www.php.net/
-
Argument 1: http://www.scriptorama.nl
-
Aantal argumenten: 3
Mocht je complexere wensen hebben dan simpelweg argumenten meegeven: je wilt bijvoorbeeld --with-hostname=localhost kunnen opgeven, dan kun je eens naar de getopt() functie of naar PEAR's Console_GetOpt package kijken.
PHP uitvoeren alsof het een executable is
Aldoor je script uitvoeren met php mijnbestand.php ziet er lelijk uit, en zeker als je bepaalde opties wilt meegeven wordt het gewoon onhandig als het vaker moet gebeuren. Gelukkig kun je op linux/bsd en unix machines in een script een interpreter meegeven op de eerste regel van het bestand. Wanneer het script volgens de permissies uitvoerbaar is en het operating system dit tegenkomt wordt het bestand uitgevoerd met die interpreter. Dit gebeurd met de zgn. hashbang notatie:
-
$ chmod a+x hello_world.php
-
$ ./hello_world.php
-
Hello, world
-
Mijn memory setting is: 100M
Conclusie
Ook op de shell kan PHP z'n mannetje staan. Al hoewel sommige commando's wat onhandig lang kunnen zijn, heb je op deze manier op je shell wel ongeveer directe toegang tot databases en bijvoorbeeld webservices.
Volg Scriptorama via RSS!
Reageer ook!
[...] Sommige scripts zijn bedoeld om alleen vanaf de commandline te draaien. Met deze constante kun je controleren of dat ook wel echt het geval is: PLAIN TEXT PHP: [...]
Door 5 PHP constantes om je scripts meer portable te maken | Scriptorama op 04.23.06 @ 1:34 pm | Permalink
[...] Zorg er voor dat dit script executable is door het volgende commando uit te voeren: # chmod a+x socket.php Zie ook dit scriptorama artikel voor meer informatie over commandline opties. [...]
Door PHP timer thread emulatie in combinatie met STDIN | Scriptorama op 05.01.06 @ 9:49 pm | Permalink
Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>