許多 PHP 專案中的純類別檔、設定檔、函數庫都省略結尾的 ?>。這不是偷懶,而是官方推薦的最佳實踐,能有效避免「Header already sent」等難除錯錯誤。本文透過兩個對比範例,解析核心原理與適用場景。
<?php
echo 123456;
// 結尾無 ?> 完全合法,執行正常
?><?php
echo 123456;
?>
<p>abc</p>
<?php // 若無上方 ?>,這裡的 HTML 會被視為 PHP 代碼導致語法錯誤
echo "more";
?>
?>??> 後的所有字元(含看不見的空白、換行、BOM)視為**直接輸出**送往瀏覽器。header() 時就會噴 Warning: Cannot modify header information - headers already sent。「PHP 閉合標籤
?>在 PHP 解析器中是**可選**的。若使用閉合標籤,任何由開發者、使用者、FTP 工具插入在標籤後的空白字元,都可能導致多餘輸出、PHP 錯誤、後續輸出無法顯示、空白頁。因此,**所有純 PHP 檔案應省略閉合標籤**,並以註釋標示檔案結束與相對路徑。」
| 不當寫法 | 適當寫法 |
|---|---|
|
|
| 檔案類型 | 是否保留 ?> | 說明 |
|---|---|---|
| 純類別/介面/Trait 定義 | ❌ 省略 | 防止被 include/require 時輸出空白 |
| 函數庫、工具類、設定檔 | ❌ 省略 | 同理 |
| 模板檔(含 HTML) | ✅ 保留 | 需切換回 HTML 模式 |
| 獨立執行的腳本(無包含關係) | 可保留可省略 | 省略較安全,習慣加結尾註釋 |
?> 會不標準?:官方文件明確說是可選,且推薦省略,符合 PSR-12 風格指南。養成習慣:純 PHP 檔案永遠不寫 ?>,檔案結尾加上 /* End of file ... */ 註釋。這行微小改動,能替你省下無數個深夜除錯 headers already sent 的時間。