核心差異速查表
| 函式 | 失敗行為 | 重複包含 | 編譯時期 | 典型用途 |
include | E_WARNING,繼續執行 | 允許(每次都執行) | 執行時 | 模板片段、條件載入、可選配置 |
include_once | E_WARNING,繼續執行 | 忽略(僅首次執行) | 執行時 | 函式庫、類定義、避免重複定義 |
require | E_COMPILE_ERROR,腳本終止 | 允許(每次都執行) | 編譯時 | 核心配置、自動載入器、關鍵依賴 |
require_once | E_COMPILE_ERROR,腳本終止 | 忽略(僅首次執行) | 編譯時 | 類/介面/特徵定義、Composer 自動載入 |
行為演示
<?php
// 檔案不存在時
include('missing.php'); // Warning,echo 'after include' 會執行
require('missing.php'); // Fatal Error,腳本停止,後續代碼不執行
// 條件包含
if (false) {
include('a.php'); // 不執行(執行時評估)
require('b.php'); // 依然會包含並編譯(編譯時掃描)!
}
// 結論:require 無視條件,include 受條件控制
編譯時 vs 執行時:效能與邏輯影響
- require / require_once: PHP 編譯階段掃描到即讀取、解析、編譯為 Opcode。
優點:OpCache 可直接快取,首次載入後極快。
缺點:檔案不存在直接報 Fatal Error,無法優雅降級。
- include / include_once: 執行到該行時才讀取、編譯。
優點:可動態決定載入哪個檔案(如多主題模板)。
缺點:每次請求執行時都需檢查、編譯(OpCache 仍可快取 Opcode,但需執行期檢查)。
路徑解析陷阱與最佳實踐
<?php
// ❌ 相對路徑:隨 include 執行位置變化而變化
include 'config.php'; // 危險
include '../config.php'; // 更危險
// ✅ 絕對路徑:基於當前檔案位置
require_once __DIR__ . '/config.php';
require_once dirname(__FILE__) . '/config.php'; // PHP 5.2 相容
// ✅ 專案根目錄常量(入口檔案定義)
define('APP_ROOT', __DIR__ . '/../');
require_once APP_ROOT . 'config/database.php';
// ✅ Composer 自動載入(現代專案標準)
require_once __DIR__ . '/../vendor/autoload.php';
效能微基準(PHP 8.2 + OpCache)
| 函式 | 首次載入 | 快取後 | 記憶體 |
| require_once | ~0.15 ms | ~0.002 ms | 極低 |
| include_once | ~0.18 ms | ~0.003 ms | 極低 |
| require | ~0.12 ms | ~0.001 ms | 極低 |
| include | ~0.14 ms | ~0.002 ms | 極低 |
OpCache 啟用後,四者差異可忽略。**選擇標準:語義正確性 > 微觀效能**。
現代專案建議規範
- Composer 自動載入(PSR-4)處理 99% 類/介面/函式: 手寫
require_once 僅用於 vendor/autoload.php 與極少數非 Composer 管理的legacy檔案。
- 配置檔、核心服務提供者:
require_once(失敗即停止,避免帶壞配置運行)。
- 視圖模板、可選擴展點:
include(允許不存在、條件載入)。
- 函式庫檔(非類):
include_once 防重複定義。
- 嚴禁在迴圈中包含: 移至迴圈外,或改用自動載入。
常見錯誤與除錯
| 錯誤 | 原因 | 解決 |
| Cannot redeclare function | 同檔案被 include/require 多次 | 改用 _once 版本 |
| Class not found | 自動載入未掃描、命名空間錯誤、大小寫不符 | 執行 composer dump-autoload,檢查 PSR-4 對應 |
| open_basedir restriction | 路徑超出 PHP 允許目錄 | 調整 open_basedir 或使用允許路徑 |
| Failed opening required | 檔案不存在、路徑錯誤、權限不足 | 用 realpath() 驗證路徑,檢查檔案權限 |
總結
require_once 是現代 PHP 專案的「主力」:編譯時載入、OpCache 友好、失敗即停、防重複定義。include 保留給「可選、動態、模板」場景。理解「編譯時 vs 執行時」、「失敗行為」、「路徑解析」三大核心差異,即可在遺留代碼重構與新專案架構中做出正確選擇。