PHPでもコマンドラインツールはできる
今日@moznionの職質テックトーク(Podcast、http://shock-sheets-tech.tumblr.com/ )を収録してきた。ひさびさでした。
まあ、私はPHPおじさんなので、PHPの話をつらつらとしてきた。内容としては、PHPが好きな人には、いまさらの事しか話してない。でも、そういう人は少ないらしいので、大丈夫との事だった。
さておき「えっ、PHPでコマンドラインツールつくれるんですか?」といわれたが、実際のところ普通に作る事ができる。
外部コマンドのSTDOUT/INとかちゃんととれるの?
popen、proc_openをつかえばよい
たとえば
<?php $fh = popen("cat > out", "w"); fwrite($fh, "write!"); fclose($fh);
<?php $fh = popen("ls -al", "r"); while($line = fgets($fh)){ echo $line; } fclose($fh);
proc_openをつかえば、STDOUT、STDINを同時に触れる。*1
TTYとかとれるの?
対話型のプログラム、たとえばsshコマンドを叩きたいとかそういうことだとおもうが、enable-ptyオプション付きでビルドされていれば、proc_openでとれる。
GetOptみたいなのどうするの、
commandoというライブラリなどがある、結構色々ある
https://github.com/nategood/commando
コマンドにできるの?shebangってどう書くの?
php command.php
ではなく、
command
にするには、たとえば
#!/usr/bin/env php <?php echo 123;
というファイルをcommandというファイル名でつくって、chmod +xすればよい。*2
CLIでプログレスバーみたいなのとか書けないでしょ?
エスケープシーケンスだせればいけるし!、PHPでもそれくらいできるし!
簡単につかうライブラリもあります。
例
https://github.com/donatj/CLI-Toolkit
*3
まあ、処理によっては(ファイルダウンロード処理とか)どうやってTickをとるのか?というのはある…けど、できなくはない、React*4とかでやるという手もある
デカイファイルとかいじれるの?無理でしょ?
バカでかい、例えば10GBあるようなテキストファイルを順次処理するとかも、バカっぽくfile_get_contentsとかで一発で読み込ませようとかしないで、普通にfopen+freadを回せばまったく問題無い。
配布は…
コマンド自体の配布も、Packagist経由でComposerからできる。たとえばphpunit。
composer global require 'phpunit/phpunit=3.7.*' # コマンド(phpunit)は~/.composer/vendor/bin/ 以下にはいる、Pathは自分で通す
追記 環境変数について
環境変数の取得も設定もできます。
<?php var_dump(getenv('USER')); putenv("MY_ENV=HOGE"); echo `echo \$MY_ENV`;
$ php env.php string(6) "uzulla" HOGE
追記 ”-q” オプションなどについて
ブコメで、kaz_hiramatsuさんに指摘された件。
「昔のバージョンだと標準出力にContetnt-typeが出力されて-qとか付けてた記憶があるけどどうなったんだろう」
結論からいえば、不要です。今のPHPは(いつからか忘れた)
・php
・php-cgi
・php-fpm
などとバイナリがバラバラになっていて、-qオプションが必要なのは、php-cgiです。これはCGI用のPHPであり(PerlなどでつくられたCGI同様に)Content-typeをSTDOUTにだします。
勿論
DBもさわれるし、DBマイグレーションツールとかもあるし、fakerとかfactrygirlみたいなのもあるし、guzzleやGoutteでMechanizeみたいなこともちゃんとできるし、IRCのクライアントライブラリとかもあるよ。
(リンクめんどいので、私のGithubのStar(https://github.com/stars/uzulla)とかみてください)
でもまあ、皆さんは書かないですよね。
まあ、結論は分かっていて
「わざわざPHPで書く必要がない」ですよね!!