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

PHP include/require/once 系列函數完整差異解析:載入機制、效能與最佳實踐

     編輯:PHP 相關知識

PHP 提供四種檔案載入語句,看似相似但行為差異關鍵。本文系統對比 include、require、include_once、require_once 的錯誤處理、載入邏輯、效能特徵、適用場景與現代替代方案 (Composer 自動載入)。

核心差異對比表

語句檔案不存在語法錯誤重複載入回傳值典型用途
includeWarning,繼續執行PHP 4.3.5+ 停止允許重複成功 1,失敗 false模板、可選配置、非關鍵檔案
requireFatal Error,腳本終止停止允許重複無 (終止)核心類別、關鍵配置、必須存在檔案
include_onceWarning,繼續停止忽略重複成功 1,失敗 false函式庫、類別定義、防重複定義
require_onceFatal Error,終止停止忽略重複無核心類別、單例載入、防重複定義

行為細節深度解析

1. 錯誤處理機制

<?php
// include: 產生 Warning,腳本繼續
include 'missing.php'; // Warning: Failed opening 'missing.php'
echo "繼續執行\n"; // 會輸出

// require: 產生 Fatal Error,腳本立即停止
require 'missing.php'; // Fatal error: Failed opening required 'missing.php'
echo "不會執行\n"; // 不會輸出

// 實際專案建議:生產環境 display_errors=Off,錯誤記錄到 log

2. 重複載入防護

<?php
// a.php
$config = ['app_name' => 'MyApp'];
function helper() { return 'helper'; }

// 主程式
include 'a.php';
include 'a.php'; // 重複執行:$config 覆蓋、函數重複定義 Fatal Error

include_once 'a.php';
include_once 'a.php'; // 第二次被忽略,安全

3. 回傳值與作用域

<?php
// return.php
return ['db' => 'mysql'];

// 使用
$config = include 'return.php'; // $config = ['db' => 'mysql']
// require 同理,但失敗時不返回

// 作用域:include 在函數內呼叫,變數為區域變數
function loadConfig() {
    include 'config.php'; // $config 只在函數內可見
    return $config;
}

4. 路徑解析規則

  • 相對路徑:相對於 **當前執行腳本** (entry script),而非被 include 的檔案
  • 絕對路徑:直接解析
  • include_path (php.ini) 會被搜尋
<?php
// index.php 在 /var/www/
// lib/config.php 在 /var/www/lib/
// lib/db.php 在 /var/www/lib/ 引用 config.php

// lib/db.php
include 'config.php'; // 相對於 index.php -> /var/www/config.php (錯誤!)

// 正確做法:使用 __DIR__
include __DIR__ . '/config.php'; // /var/www/lib/config.php ✓

效能特徵

關鍵點:PHP 7+ OpCache 啟用後,_once 版本效能差異可忽略。**首選 require_once 載入類別/函式庫**,確保單一載入與錯誤即時暴露。

現代最佳實踐:Composer PSR-4 自動載入

手動 include/require 已是反模式。現代 PHP 專案 (Laravel, Symfony, 獨立庫) 全部使用 Composer 自動載入:

1. 定義命名空間對應 (composer.json)

{
    "autoload": {
        "psr-4": {
            "App\\": "src/",
            "MyLib\\": "lib/"
        },
        "files": ["src/helpers.php"] // 全域函式檔
    }
}

2. 執行生成自動載入器

composer dump-autoload -o # -o 優化為 class map

3. 入口檔案單一引入

<?php
// public/index.php
require_once __DIR__ . '/../vendor/autoload.php';

// 之後直接使用類別,無需任何 include
use App\Controllers\UserController;
use MyLib\Utils\StringHelper;

$ctrl = new UserController();
echo StringHelper::slug('Hello World');

遷移指南:從手動 include 到自動載入

  1. 整理專案結構,依 PSR-4 規範目錄 (如 src/Controller/UserController.php)
  2. 類別檔案頂部加入 namespace App\Controller;
  3. 移除所有 include/require 類別檔案的呼叫
  4. 全域函式集中到 helpers.php,在 composer.json files 註冊
  5. 入口檔案僅保留 require 'vendor/autoload.php';
  6. 執行 composer dump-autoload -o

特殊場景仍需手動載入

  • 動態載入插件/模組:foreach (glob('plugins/*/bootstrap.php') as $f) require_once $f;
  • 條件式載入配置:if (file_exists($envFile)) require $envFile;
  • 模板引擎編譯輸出:include $compiledTemplatePath;
  • 舊專案逐步遷移過渡期

常見誤區

include_once 效能差很多
OpCache 下差異微乎其微,安全性收益遠大於成本
用 include 載入類別定義
重複請求會導致 "Cannot redeclare class" Fatal Error
相對路徑以為相對於當前檔案
實際相對於執行入口,必須用 __DIR__
require 有回傳值可接收
require 失敗直接 Fatal Error,無回傳值;只有 include 有回傳值

總結:**類別/函式庫 → require_once (或更好:Composer 自動載入)**,**模板/可選配置 → include**。現代專案應盡早遷移至 PSR-4 自動載入,消除手動路徑管理負擔,享受 IDE 完整支援與部署一致性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
語句編譯快取 (OpCache)重複檢查開銷記憶體
include/require✅ 被快取無正常
include_once/require_once✅ 被快取極小 (查詢已載入表)略高 (維護載入表)