首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP include() 與 require() 差異深度解析:從底層機制到最佳實踐指南

     編輯:PHP 相關知識

核心差異速查表

底層機制原理

include():運行時動態包含

<?php
// 編譯階段:僅生成「執行 include 指令」的 opcode
// 運行階段:遇到 include 才讀取檔案、編譯、執行

if ($condition) {
    include 'optional_module.php'; // 條件成立才載入
}

// 迴圈中動態包含不同檔案
foreach ($modules as $module) {
    include "modules/{$module}.php"; // 每次迴圈重新編譯
}

關鍵點:PHP 4.3.5 以前,檔案不存在僅發出 Warning 繼續執行;之後版本統一行為。

require():編譯期靜態包含

<?php
// 編譯階段:直接將檔案內容「展開」到當前 opcode 流中
// 相當於將 require 'config.php' 替換為 config.php 完整內容

require 'core/Database.php'; // 必須存在,否則編譯失敗
require 'config/app.php';    // 設定檔缺失無法運行

// 即使在條件判斷中,require 也會被編譯期處理
if (false) {
    require 'never_used.php'; // 仍會嘗試包含,檔案不存在報錯
}

效能深度對比

微觀基準測試

<?php
// 測試檔案:simple.php 內容 

// include 版本
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    include 'simple.php';
}
echo "include: " . (microtime(true) - $start) . "s\n";

// require 版本
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    require 'simple.php';
}
echo "require: " . (microtime(true) - $start) . "s\n";

/* 典型輸出(PHP 8.0+,OpCache 啟用):
include: 0.012s
require: 0.008s
差異微小,OpCache 將編譯結果快取,運行期差異極小
*/

/* OpCache 關閉時差異明顯:
include: 0.45s  (每次重新編譯)
require: 0.12s  (編譯期展開,運行期無額外開銷)
*/

效能結論

  • OpCache 啟用(生產標配):兩者效能差異可忽略,編譯結果均被快取
  • OpCache 關閉(開發環境):require 顯著快於 include
  • 迴圈/高頻呼叫場景:優先 require_once/include_once 避免重複包含

進階變體:_once 系列

特性include()require()
檔案不存在發出 Warning(警告),腳本繼續執行拋出 Fatal Error(致命錯誤),腳本立即停止
效能特徵每次執行都讀取、解析、編譯編譯階段即包含檔案內容(類似 C #include)
條件包含支援動態條件判斷無條件包含(編譯期決定)
返回值處理可接收被包含檔案的 return 值同支援
適用場景模板檔案、條件載入、非核心依賴核心類別、設定檔、必要依賴
<?php
// 類別定義檔:必須用 require_once 防止重複定義錯誤
require_once 'models/User.php';
require_once 'interfaces/RepositoryInterface.php';
require_once 'traits/Loggable.php';

// 設定檔:require_once 確保單一實例
require_once 'config/database.php';
require_once 'config/redis.php';

// 模板片段:include_once 允許條件載入
if ($showSidebar) {
    include_once 'templates/sidebar.php';
}

實戰最佳實踐指南

1. 現代 PHP 專案結構(PSR-4 + Composer 自動載入)

<?php
// 入口檔案:僅需引入自動載入器
require_once __DIR__ . '/vendor/autoload.php';

// 其餘類別透過命名空間自動解析,完全不需要手寫 include/require
use App\Models\User;
use App\Services\PaymentService;

$user = new User();
$payment = new PaymentService();

核心原則:應用層代碼零 require/include,全權交給 Composer 自動載入器。

2. 僅在必要時手動包含

  • 第三方無 Composer 支援的舊庫
  • 動態模板渲染(View 層)
  • 條件載入的大型功能模組(Code Splitting)
  • 設定檔(環境差異大)

3. 路徑解析最佳實踐

<?php
// 絕對路徑:最安全、效能最好
require_once __DIR__ . '/../config/app.php';

// 相對路徑:依賴 include_path,易出錯
// require_once 'config/app.php'; // 不推薦

// 動態路徑:使用 Dirname 遞歸
$root = dirname(__DIR__, 3); // 向上 3 層
require_once $root . '/shared/kernel.php';

4. 錯誤處理模式

<?php
// 核心依賴:require 失敗即停止(正確行為)
require_once __DIR__ . '/bootstrap.php';

// 可選功能:include 失敗記錄日誌但不中斷主流程
if (@include_once __DIR__ . '/plugins/analytics.php') {
    Analytics::init();
} else {
    error_log('Analytics plugin not found, skipping');
}

// 條件載入:include 允許運行時判斷
$theme = getUserTheme();
include_once __DIR__ . "/themes/{$theme}/functions.php";

常見錯誤與避坑

函數行為使用建議
include_once()檢查是否已包含,未包含才執行 include模板片段、可能重複引入的工具檔
require_once()檢查是否已包含,未包含才執行 require類別定義、介面、Trait、核心設定(最常用)
錯誤後果修正
類別檔用 include重複包含導致「Cannot redeclare class」改用 require_once
核心設定用 include檔案缺失靜默失效,後續報詭異錯誤改用 require
迴圈中用 require編譯期錯誤(不能在迴圈中 require 變數路徑)改用 include
混用導致依賴混亂難以追蹤載入順序、循環依賴統一用 Composer 自動載入
忽略 OpCache 影響開發環境以為 require 快,生產其實無差理解 OpCache 機制,生產必開

總結:決策流程圖

需要包含檔案
    │
    ├─ 是類別/介面/Trait/核心設定? → 是 → require_once
    │
    ├─ 是模板/視圖/可選模組? → 是 → include_once
    │
    ├─ 需在迴圈/條件中動態載入? → 是 → include
    │
    └─ 以上皆否 → require_once(預設最安全)

現代 PHP 開發:99% 場景由 Composer 自動載入處理,手寫 require/include 僅存在於入口檔、設定檔、模板渲染、動態模組載入等邊界場景。理解底層差異是為了在邊界場景做正確選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved