Jak si zjednodušit práci s PHP projektem pomocí příkazové řádky

Pokud si myslíte, že s PHP můžete pouze generovat dynamické webové stránky, mýlíte se. PHP je v dnešní době poměrně univerzální jazyk a škála úkolů, které s ním lze řešit, sahá například až k vytváření grafických uživatelských rozhraní v PHP-GTK. Pro webového vývojáře je z těchto dalších úkolů zřejmě nejzajímavější využití PHP v příkazové řádce.
Nálepky:
Takové nástroje vám mohou usnadnit život automatizací různých úloh a využijete je pravděpodobně i při vzdálené práci se servery přes SSH.
Proč PHP?
Mohu to přece udělat v Pythonu, Bashi, Perlu, Céčku, … No řekněme, že to má své výhody. Pokud člověk podstatnou část života programuje v PHP a většinu úloh v něm udělá nejrychleji a s největší jistotou, pak je logické, že si tentýž jazyk vybere i pro skripty ve svém operačním systému nebo pro malinké aplikace.
Nebo si představte, že máte webovou aplikaci, která chce cronem spouštět nějaké úlohy. Psát takové úlohy veřejně přístupné (tzn. že cron vykoná HTTP požadavek na dané URL a tím se spustí skript) je poměrně nebezpečné a psát je v jiném jazyce je neefektivní – máme-li hotovou aplikaci s připojením k databázi a propracovaným modelem, je škoda toho rovnou nevyužít a psát to celé znova třeba v Pythonu.
Instalace a spouštění
K tomu, abyste mohli PHP využívat i v příkazové řádce, tedy CLI, většinou nejsou zapotřebí žádné složité kroky. Například v linuxové distribuci Ubuntu vám stačí doinstalovat balíček php-cli
, na Windows zase jen pro větší pohodlí přidáte své php.exe
do systémové cesty. Pokud do příkazové řádky napíšete $ php --version
a systém se netváří nijak ublíženě, máte v podstatě vyhráno a můžete začít psát své skripty. Ty následně spouštíme jednoduše: $ php helloworld.php
.
Automatizace práce s projektem
Také se může hodit napsat si jednoduché skripty pro automatizaci práce nad určitým projektem. Já to osobně dělám často a musím přiznat, že mě to naučil framework Symfony, který má přes příkazy v CLI automatizováno opravdu mnohé. Přijde mi to velmi pohodlné a tak si tento návyk v rámci možností přenáším i do jiných pracovních prostředí, třeba i do u nás populárního frameworku Nette.
Školení Nette
Pokud vás zajímá, „co vlastně na tom Nette všichni vidí, přijďte na školení Vývoj webových aplikací v Nette Framework. Dozvíte se přímo od autora frameworku nejen jak psát webové aplikace v Nette, ale hlavně jak je psát správně. Školení proběhne 9. – 10. 3. 2011 vždy od 10:00 v Praze.
Školení je určeno všem programátorům v PHP, kteří se chtějí naučit tvořit webové aplikace rychle a kvalitně, bez bezpečnostních děr. Jako aplikační rámec slouží Nette Framework.
Nette je přitom na CLI připravené – existuje experimentální, nicméně dobře fungující CliRouter a jako název prostředí se v příkazové řádce automaticky nastaví console
. Abych nemusel moc přemýšlet nad presentery, vytvořím si jen jeden, TaskPresenter
, který bude obsluhovat jednotlivé úlohy. Mohu si potom i do adresáře s projektem vytvořit malý Bash skript, nazvaný například command
, jenž mi se směrováním požadavků pomůže:
#!/bin/bash script_dir=`dirname "$0"` exec php "$script_dir/index.php" "task:$@"
Aby toho nebylo málo, mohu si do systémové cesty vytvořit ještě komplexnějšího pomocníka, opět v Bashi. Ten bude dostupný odkudkoliv ze systému. Pojmenujme ho stejně jako projekt, dejme tomu slevonator3000
:
#!/bin/bash cd ~/workspace/.../slevonator3000/ if [ "$1" = "ssh" ]; then # connect to server via ssh ssh honzajavorek@225.225.225.225 elif [ "$1" = "cc" ]; then # clear cache rm -rf ./slevonator3000/temp/cache/* ./slevonator3000/temp/sessions/*; exit elif [ "$1" = "check" ]; then # check code by Nette Code Checker php ./slevonator3000/tools/Code-Checker/code-checker.php -ld ./slevonator3000/ exit elif [ "$1" = "fix" ]; then # fix code by Nette Code Checker php ./slevonator3000/tools/Code-Checker/code-checker.php -fld ./slevonator3000/ exit elif [ "$1" = "git" ]; then shift 1 # before adding files to git... if [ "$1" = "add" ]; then # dump database schema into sql file ./command schema --dump # automatically fix all code php ./slevonator3000/tools/Code-Checker/code-checker.php -fld ./slevonator3000/ fi # delegate to git git "$@" exit else # else delegate to CLI interface of my project written in PHP ./command "$@" exit fi echo "Unknown command."
Jak vidíte, nyní se napsáním $ slevonator3000 ssh
mohu odkudkoliv ze systému ihned připojit na produkční server. Příkaz $ slevonator3000 cc
mi zase smaže cache (to musím udělat v Bashi, protože bude-li v Nette potřeba promazat cache, nespustím na něm kvůli chybě logicky ani žádnou CLI úlohu), pomocí $ slevonator3000 check
nebo $ slevonator3000 fix
mohu různě dolešťovat podobu svého kódu a nakonec přes $ slevonator3000 git
mohu přistupovat i k verzovacímu systému. Cokoliv jiného propadne přímo na příkaz command
ve složce s projektem a tedy i na TaskPresenter
v Nette. Příkladem takového volání může být ve skriptu použité ./command schema --dump
, což je má PHP úloha na export databáze projektu do SQL souboru. Obdobně jednoduché pomocníky by šlo samozřejmě napsat i ve Windows PowerShell nebo jako dávky.
Specifika CLI
Při práci s PHP v CLI je třeba myslet na některá jeho omezení a je dobré si uvědomit, čím disponuje navíc. Nelze například zjistit IP adresu a ani žádné jiné údaje okolo HTTP požadavku. To je sice logické, protože žádné HTTP není ve hře, ale nejedna aplikace, jejíž kód byste rádi ve svých CLI úlohách recyklovali, na takových údajích závisí. Pro zjištění, kde se skript nachází, se mi osvědčila funkce php_uname, konkrétně php_uname('n')
. Tak snadno poznám, jestli spouštím skript na mém počítači lisa, nebo na produkčním serveru.
Čím PHP v CLI disponuje navíc? Máte k dispozici nekonečný max_execution_time
, což je důležité pro dlouhé náročné úlohy. Pamatujte však, že jazyk, v němž programujete, je stále PHP, a pokud vás tedy nezastaví čas, udělají to za něj jiné zdroje. Zapomeňte na psaní výkonných skriptů – PHP příliš paměť uvolňovat neumí a byť se můžete snažit, ale skript zpracovávající velký objem dat vám v tomto případě často zhyne na její nedostatek, ať už mu jí přidělíte v php.ini
kolik chcete.
Až budete paměťová omezení v php.ini
nastavovat, nezapomeňte, že CLI má tento soubor často svůj vlastní, abyste mohli mít různá nastavení pro skripty v prohlížeči a pro ty v konzoli. Hodí se mít také na paměti seznam všech nastavení, která jsou v PHP CLI natvrdo vnucena.
Naučte se PHP s Jakubem Vránou
Úvod do PHP – 20. 4. 2011 | 10:00 | Praha
Jednodenní kurz Úvod do PHP je určen všem současným a budoucím webovým vývojářům, kteří se chtějí od základu seznámit s programovacím jazykem PHP.
Kurz programování v PHP 5 – 21. 4. 2011 | 10:00 | Praha
Jednodenní kurz programování v PHP 5 je určen všem webovým vývojářům, kteří se chtějí do hloubky seznámit a sžít s programovacím jazykem PHP ve verzi 5.
Závěrem
PHP v příkazové řádce je dobrý pomocník, ale zlý pán. Jestliže si chcete usnadnit práci a chcete tentýž kód využít jak ve webové aplikaci, tak i v úloze pro cron, sáhněte po něm. Pokud byste v něm ale chtěli psát komplexnější konzolové aplikace, zřejmě brzy narazíte na nepříjemnosti a zjistíte, že pro takový úkol zde máme spíše jiné jazyky. Také jsme si ukázali, že se může vyplatit oprášit své znalosti Bashe nebo dávkových souborů pro napsání všudypřítomných pomocníků. Odladění pro vaše konkrétní potřeby sice zabere nějakou dobu, ale následná možnost udělat stále se opakující práci jen vepsáním několika znaků do tajemného černého okna nakonec může ušetřit nejen čas, ale i nervy.
Já taky třeba přikládám k PHP aplikacím makefile, hodí se třeba na následující úlohy:
– vygenerovat z pracovní kopie tarball pro distribuci (pracovní data a konfiguraci nahradí demo daty)
– nahrát tarball na distribuční server (no to za mě dělá spíš git(hub) s .gitignore)
– nainstaluje aplikaci (u klienta) = nastavi permissny,…
– stahne novou verzi aplikace a nainstaluje ji bezpecne misto stare
– dumpnout/odzálohovat DB/data (muze volat PHP pro nacteni hesla od DB z konfiguraku)
– nahrát zálohu zpět
– smazat z disku cache (pokud aplikace neco cachuje)
– vyhleda v kodu vsechny vyskyty retezce „TODO“
– zkompiluje vsechny php,css,js,html do co nejmene nejkratsich souboru (zavisi na aplikaci, pro produkcni prostredi je lepsi mit vsechny js v jednom souboru, v html nemit zbytecny whitespacy, atd… navic pokud se celou aplikaci podari ulozit do jedinyho php souboru, pusobi pak pro koncovyho uzivatele kompatknejsim dojmem)
– zobrazi napovedu k makefile (pokud uzivatel napise make help nebo jen make)
Takovy Makefile, ktery by si PHP programator mohl upravit pro svoje potreby je treba zde:
https://github.com/Harvie/haiwiki/blob/master/Makefile
Ak sa podari celu aplikaciu ulozit do jedineho php suboru, tak posobi na koncoveho uzivatela kompaktnejsim dojmom?
Neviem ci mozem suhlasit s tymto tvrdednim. Netvrdim, ze plati presny opak, ale podla mna koncovy uzivatel ani vobec netusi ci je php aplikacia v jednom alebo v 20 suboroch. Nema ako. A z programatorskeho hladiska sa mi nezda rozumne vsetko davat do jedneho suboru. Z toho vie vziknut pekny gulas po case. Ale pokial ide iba o „skompilovanie“ vyslednych zdrojovych suborov do jedneho, do ktoreho sa uz nebude zasahovat, tak nemam ziadne vyhrady.
Pozor, nesmíte brát všechno černobíle, ode zdi ke zdi, buď – anebo! Programátor, vývojář, má stále aplikaci rozdělenou a pracuje tak, jak je zvyklý. Ovšem PŘED DEPLOY se udělají tyto operace – minifikace apod. kvůli pohodlnějšímu zpracování. Myslím, že nikdo soudný nenavrhuje sloučení všech skriptů do jednoho, a v něm dál vyvíjet :)
Díky! Makefile mě nenapadl. Doteď jsem používal udělátko v Pythonu :)
interaktivna konzola php -a
a podporuje aj autocomplete :)
dobrý tip
dobry hudobny vkus :)
Díky :-)
Jen by jsem rad upozornil na to, ze treba router m0n0wall (a odvozene projekty) ma konfiguracni skripty take psane v PHP:
http://m0n0.ch/wall/
m0n0wall is probably the first UNIX system that has its boot-time configuration done with PHP, rather than the usual shell scripts, and that has the entire system configuration stored in XML format.
A to je jako přednost? Bootovat kvůli PHP bloatware o pět sekund dýl (naváíc když zpravidla některý změny konfigurace vyžadujou restart) a parsovat zbytečně ukecanej XML formát, kterej se navíc ani needituje moc dobře.
Kdyby udělali kombinaci dejmetomu třeba python (ten je alespoň prekompilovanej do bytekódu) + třeba Yaml nebo JSON, kterej se hezky edituje i snadno parsuje, tak nic neřeknu, ale jak xml, tak php se mi pro tydle účely zdá hodně nevhodně vybraný…
Pro inspiraci aplikace, ktera umoznuje veskerou obsluhu Drupalu z prikazove radky. Treba tam najdete neco, co se vam bude hodit k vasemu projektu:
http://drush.ws/
Kdybyste chtěli psát make pomocí PHP, můžete pro inspiraci juknout i sem https://github.com/nette/build-tools