uzullaがブログ

uzullaがブログです。

PHPでもコマンドラインツールはできる

今日@moznionの職質テックトークPodcasthttp://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で書く必要がない」ですよね!!

*1:当然デッドロックを作りやすいので、お勧めはしないけど

*2:Windowsは…w

*3:このライブラリに限った話ですけど、横幅がでかすぎると、表示がバグるような気がする

*4:イベント駆動