Omit the PHP closing tag "?>"

自從開始改用 ZF 後,開始慢慢的調整自己的 code style,過程也許會痛苦,但相信結果應該會是甜美的。在 ZF 的 Coding Standard 裡有一段是這麼寫的:

For files that contain only PHP code, the closing tag (“?>”) is never permitted. It is not required by PHP, and omitting it prevents the accidental injection of trailing whitespace into the response.
- Zend Framework Coding Standard

看不太懂哪來的 injection,後來再翻了一下 PHP 的官方資料才發現也有提到這段:

The closing tag of a PHP block at the end of a file is optional, and in some cases omitting it is helpful when using include() or require(), so unwanted whitespace will not occur at the end of files, and you will still be able to add headers to the response later. It is also handy if you use output buffering, and would not like to see added unwanted whitespace at the end of the parts generated by the included files.
- PHP.net Instruction separation

後來自己動手做了一下實驗:

// 檔名 inc.php

<?php
// do something
?>
// 檔名:test.php

<?php
require_once('inc.php');
session_start();
?>

執行 test.php,看起來是沒什麼大問題;不過如果在 inc.php?> 後面再按幾下 enter,多加幾行空白行,test.php 就會丟出警告訊息「Cannot send session cookie – headers already sent by..」,如果把 inc.php 的 ?> 拿掉就 ok 了。

原來,在 ?> 之後多按的幾個 enter(newline)也會被當成資料丟給瀏覽器,所以如果 include 了這樣的檔案進來,會讓 header()session_start() 之類的指令丟出「headers already sent by..」的警告訊息,而如果省去結尾的 ?> 則可以避免這個問題。

果然魔鬼都是還是躲在細節裡,PHP 的手冊還是要多看啊!

順帶一提,ZF 有 PDF 版的離線手冊了,一千多頁,雖然不見得有比線上方便,但沒網路的時候倒還不錯用(我是把它放到 PDA 裡,上廁所可以看)