1
日記を習慣にしようと思ったけど数日置いてしまって後でまとめる現象。
むかしはてなダイアリーってサイトでやったわー。そのうち追従できなくなるやつ。
2
先週Flycheckに送ってたプルリックだけど、そろそろまとまるかな。
github.com
機械翻訳頼りの怪しい英語でしか情報を残しておかないのはどうかと思ふので、日本語でも書いておくね。
FlycheckってのはEmacs向けのシンタックスチェッカーのコレクションで、GNU Emacs標準添付とかじゃないんだけど、これだけ入れておけばいい感じに文法違反をチェックしてくれるやつね。
PHPやってると、趣味でも仕事でもPHPでスクリプトを書きたくなることって、よくあるじゃないですか。ここではshebang)がついて、コマンドラインから起動されることを意図したPHPスクリプトのことです。
さて、モダンなPHPはnamespace
を持つものです。以下のようなhello.php
があったとしますね。
#!/usr/bin/env php
<?php
namespace Flycheck\Sample;
echo "Hello", PHP_EOL;
このスクリプトは文法違反ではありません。特定の文脈では。
PHPコマンドには文法チェッカが含まれて居り、php -l
でSyntax errorがないか確認することができます。php -l hello.php
で文法チェックをすると、文法違反のスクリプトではないことがわかります。
しかし不思議なことに、Flycheckを通すとこのスクリプトはSyntax errorだと警告を受けることになります。
それはなぜか。
@tadsanは終始てきとーな言動しかしないのでPHPは制禦構造を持ったテンプレートエンジンだとかPHPはテンプレートエンジンじゃない。調子に乗るなとか雑に言ったりするんですけど、この問題はまさにPHPの両面性を示したものです。
本来のPHPは、みなさまがよく御存じの通りWebページを作成するためのテンプレートエンジンのような言語です。
<p>今日は<?= date('Y年m月d日') ?>です。</p>
これは文法的には以下のスクリプトとおよそ等価です。
<?php
echo '<p>今日は';
echo date('Y年m月d日');
echo 'です。</p>', PHP_EOL;
ここでふと疑問がよぎります。
#!/usr/bin/env php
<?php
これは echo '#!/usr/bin/env php', PHP_EOL;
と等価ではないか、と。
% ./hello.php
Hello
% php ./hello.php
Hello
% php -e < ./hello.php
PHP Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script in - on line 4
Fatal error: Namespace declaration statement has to be the very first statement or after any declare call in the script in - on line 4
おやおや、これは不穏……! Fatal errorになっちゃった。
hello.php
からnamespace
の含まれた行だけを抜いたhello2.php
を作ってみますね。
% php -e < ./hello2.php
#!/usr/bin/env php
Hello
ビンゴ! #!/usr/bin/env php
も標準出力されてきました。つまり、 echo '#!/usr/bin/env php', PHP_EOL;
と等価だ。「まじかよ」と思ったら疑念を放置せず、自分の環境で動かしてみてくださいよ。
ここから導きだされる結論は「PHPはCLIでファイルを直接実行する場合だけshebangを無視する」です。php -e
、つまり標準入力からスクリプトを読み込んだ場合は対象になりません。この現象自体はよく知られたもので、shebangのついたファイルをinclude
/require
したときにはshebangが標準出力される羽目になります。
さて、namespace
はPHPスクリプトファイル内の最初(ただしdeclare
を除く)に書かなければいけないので、echo '#!/usr/bin/env php';
に相当する文が存在するとこのルールに違反し、Fatal errorになるわけです。
3
話が長くなったので節を分けますが、これを回避するための結論は「文法チェック時には標準入力は利用せずファイルを利用する」です。
4
qiita.com
5
木曜はnomikai.elと称して、Emacsっぽいひとたちと飲んだ。
6
Emacsの M-x はコマンドパレットだ!!