はじめに
タグの外側の文字列はどういう扱いなのかの続きです。PHPタグの外側に文字列を書くとecho文のように扱われると書いたのですが、では中身が空になる?><?php
を任意の所に書いていいか?というのが疑問でした。
結論
タイトルに書いたとおり、PHPの終了タグ?>
はそこにセミコロンがあるものとして扱われます。これはマニュアルの「命令の分離」に書いてあります。ここの書き方だと書き忘れても補ってくれるぐらいのものであるようにも読めるのですが、実際にはそこに必ずセミコロンがある扱いになります。ですから、セミコロンを置けないところに終了タグ?>
を書くと構文エラーになります。
<?php
class ?><?php Foo // これは構文エラー
{}
namespace Foo // これはOK
?>
<?php
for ($i = 0 ?><?php $i <10 ?><?php $i++) { // これもOK(普通はやりませんが)
}
switch文の例
ところでそもそもの発端の「phpでswitch文の「switch($hoge)★ここ★{case0:」に改行いれるとエラーになる。」で
<?php
$i = 0;
?>
<?php
switch($i){
?>
<?php
case 0:
?>
<p>aaa</a>
<?php
break;
}
はOKでした。上の原則に従うとswitch文の所は
switch($i){
;
case 0:
...
で、最初のcaseの手前にセミコロンがあることになるのですが、これアリなの?というのが疑問になると思います。マニュアルの「switch」のところにもそれらしいことは書いていません。(もっとも最初のcase文の手前に実行文を書いてはいけないということも明記されていませんが)
例によってソース(Zend/zend_language_parser.y
)を当たってみます。
switch_case_list:
'{' case_list '}' { $$ = $2; }
| '{' ';' case_list '}' { $$ = $3; }
| ':' case_list T_ENDSWITCH ';' { $$ = $2; }
| ':' ';' case_list T_ENDSWITCH ';' { $$ = $3; }
;
つまり単独のセミコロン1個だけはOKとわざわざ書いてありました。どうしてこうなってるんでしょうか? PHP奥が深い...
追記:
<?php switch ($i) { ?>
<?php case 1: ?>
ほげほげ
<?php break; ?>
<?php case 2: ?>
ふがふが
<?php break; ?>
<?php } ?>
のような書き方を許容したかったのかもしれません。セミコロンが許されてないと最初のcaseだけswitchとまとめて書かなくてはいけなくなって書き方の統一感がなくなります。
<?php switch ($i) {
case 1: ?>
ほげほげ
<?php break; ?>
<?php case 2: ?>
ふがふが
<?php break; ?>
<?php } ?>
さらに追記:
switchのマニュアルを確認したときに最後の方に
case の最後はコロンではなくセミコロンとすることもできます。
と書いてあって変な仕様だなと思っていたのですが、これと終了タグがセミコロンであることをあわせると、次のような書き方が可能になるのですね。
<?php switch ($i) { ?>
<?php case 1 ?>
ほげほげ
<?php break ?>
<?php case 2 ?>
ふがふが
<?php break ?>
<?php } ?>
こういうのを見るとPHPってもともとはHTMLに埋め込む言語だったんだなと実感します。普段は先頭におまじないのように<?php
と書いたらあと閉じることなんてないですが。