hnwの日記

PHPの対話モードでuseしたら1行後には忘れられてた

PHPの対話モードに関する小ネタです。PHPコマンドは-aオプションつきで起動すると対話モードになります。libreadlineかlibeditを有効にしてビルドしたPHPであれば、下記のようにプロンプトが表示されて入力を促されます。

$ php -a
Interactive shell

php >


このモードではEnterを打つたびに式が評価され、一度定義した変数や関数はずっと記憶してくれています。また、Emacs風のキーバインディングも効きますので、簡単な実験をするには最適です。たとえば下記のような感じになります。

$ php -a
Interactive shell

php > function fib($n) { return ($n<=1)?$n:fib($n-2)+fib($n-1); }
php > var_dump(fib(10));
int(55)
php >


ところで、この環境ではPHP 5.3以降で使えるはずのuseが思い通りに動きません。

$ php -a
Interactive shell

php > use DateTime as DT;
php > $dt = new DT('today midnight');
PHP Fatal error:  Class 'DT' not found in php shell code on line 1

Fatal error: Class 'DT' not found in php shell code on line 1
php >


use文でDateTimeクラスのエイリアスとしてDTクラスを宣言したつもりでしたが、そんなクラスは知らないと言われてしまいました。ところが、これを1行にまとめて書くと期待通りに動きます。

$ php -a
Interactive shell

php > use DateTime as DT; $dt = new DT('today midnight');
php > var_dump($dt->format("c"));
string(25) "2012-05-03T00:00:00+09:00"
php >


納得いかない気がしますが、そういうもんなんでしょうかね…。



追記(5/14 9:30)

同様のバグレポがとっくに出てました。忘れるのは仕様のようです( PHP :: Doc Bug #55155 :: Cannot use non-bracketed namespaces in interactive shell on multiple lines)。

対話型モードでは行末までのヒトカタマリが評価できそうならevalするような挙動になっており、use foobar;とだけ書かれたらその行だけを評価してしまうとのことです。