[PHP] テンプレートエンジンやヒアドキュメントにおける改行文字の扱い

PHPは言語構造としてテンプレートエンジン(文書の出力機能)があり、一方でヒアドキュメントの機能もあるが、基本的に見た目のまま出力される。

ただし改行については、いずれもやや癖があるので注意。

テンプレートエンジン

PHPタグ <?php の閉じタグ ?> の直後の改行は無視される。

PHP:
[php]
first-line <?php echo 'php’; ?>
second-line
[/php]

出力:
[text]
first-line phpsecond-line
[/text]

このため、以下のような書き方をするとコードの見た目上はきれいだが、出力されたテキストは意図したものにならない。

例1

PHP:
[php]
<div>
<?php echo 'sample’; ?>
</div>
[/php]

出力:
[text]
<div>
sample</div>
[/text]

例2

PHP:
[php]
<div>
<?php if (b) : ?>
sample
<?php endif; ?>
</div>
[/php]

出力:
[text]
<div>
sample
</div>
[/text]

これらを防ぐには、PHPタグの直後にはかならず改行をひとつ余計に入れ、できるだけPHPタグの前にはタブやスペースを入れないようにする。

例1

[php]
<div>
<?php echo 'sample’; ?>

</div>
[/php]

例2

[php]
<div>
<?php if (b) : ?>
sample
<?php endif; ?>
</div>
[/php]

出力:
[text]
<div>
sample
</div>
[/text]

ヒアドキュメント

最後の行(終端 IDの直前)の改行は無視される。

PHP:
[php]
echo <<< EOD
first
EOD;

echo 'second’
[/php]

出力:
[text]
firstsecond
[/text]

この場合も、対応としては改行をひとつ余計に記述しておく。

PHP:
[php]
echo <<< EOD
first

EOD;

echo 'second’
[/php]

出力:
[text]
first
second
[/text]

PHPファイル

上記とは異なり、PHPファイルそのものは最後の改行が省略されるということはない

ただし、見た目上とは異なり、ファイルの終端が改行とみなされることはないので注意が必要(一部のワープロソフトなどとは異なるということ)。

sample1.php
[php]
<?php echo 'first’; ?>

second
[/php]

この場合、以下のように出力される。

[text]
first
second
[/text]

このあたりをきちんと理解しておかないと、複数のファイルをインクルードした際に、意図しない形での出力になってしまう。

sample2.php
[php]
<?php echo 'third’; ?>

fourth
[/php]

link.php
[php]
require 'sample1.php’;
require 'sample2.php’;
[/php]

出力
[text]
first
secondthird
fourth
[/text]

コーディングの際によくやるように、常に最後は改行で終わるようにしたほうがいいかもしれない。

[php]
<?php echo 'first’; ?>

second
# EOF
[/php]

補足:PHPの閉じタグを省略しよう

上記のとおり、PHPタグ直後の改行は無視されるため、以下のようにPHPのコードのみを記述した場合は、最後に改行がひとつあってもコード側でechoなどによって何かを出力しないかぎり、何も表示されない。

[php]
<?php
function doSample() {
//…
}
?> # \n
# EOF
[/php]

裏を返せば、最後に複数の改行があった場合、テキストとして改行文字が出力されることになる。

sample.php
[php]
<?php
function doSample() {
//…
}
?> # \n
# \n
# EOF
[/php]

ほとんどの場合これでも問題はないが、ヘッダ情報などを出力する際にエラーになってしまうことがある。

[php]
<?php
require 'sample.php’;
header('Location: http://www.example.com/’);
?>
[/php]

header()では、それを実行する前に他の出力があることを認めていないため。

関数やクラスのインクルードの際に問題になりやすいので、昔から閉じタグ「?>」を省略することが推奨されている(PHPの公式リファレンスの例では、相変わらず閉じタグを書いているが)。

[php]
<?php
function doSample() {
//…
}

[/php]

これでファイルの末尾にいくら改行があっても、何も出力されない。

言語仕様として許されている方法なので、PHPコードのみのファイルでは基本的にこういう書き方をするようにしよう。

PHP

Posted by takasho