當執行 include 'a.php' 時,PHP 依次在以下路徑查找:
php.ini 或 set_include_path() 設置)。__DIR__ 或 getcwd(),視調用方式而定)。./ 或 ../ 開頭,僅在當前工作目錄相對路徑查找,忽略 include_path。project/
├── a.php // 入口文件
├── include/
│ ├── b.php // 被 a.php 包含
│ └── c.php // 被 b.php 包含
<?php
include 'include/b.php';
?>
<?php
include 'c.php'; // 相對於 b.php 所在目錄 (include/) 查找 → 找到 include/c.php
include 'include/c.php'; // 相對於 a.php 所在目錄 (project/) 查找 → 也找到 include/c.php
echo 'c.php loaded';
?>
<?php
echo 'c.php executed';
?>
兩種寫法在 b.php 中均能正確載入 c.php。說明 PHP 的查找機制同時兼顧了「被包含文件所在目錄」和「主腳本所在目錄」。
// 性能從慢到快:
include 'a.php'; // 最慢:遍歷 include_path 每個目錄
include './a.php'; // 中等:僅查當前工作目錄
include '/full/path/a.php'; // 最快:直接訪問文件系統,零查找開銷
include_path 數組,對每個目錄拼接路徑發起 stat() 系統調用檢查文件是否存在,IO 開銷大。stat(),命中即載入,無遍歷開銷。<?php
// 公共入口/配置文件(如 common.php、bootstrap.php)
define('APP_ROOT', __DIR__); // 當前文件所在目錄絕對路徑
// 業務代碼中統一使用
include APP_ROOT . '/config/database.php';
include APP_ROOT . '/lib/utils.php';
require_once APP_ROOT . '/vendor/autoload.php';
| 項目 | 常量定義 | 用法示例 |
|---|---|---|
| Emlog | define('EMLOG_ROOT', dirname(__FILE__)); | include EMLOG_ROOT . '/config.php'; |
| ThinkPHP | define('APP_PATH', __DIR__ . '/application/'); | require APP_PATH . 'common.php'; |
| Laravel | app_path()、base_path() Helper | require base_path('vendor/autoload.php'); |
| WordPress | ABSPATH (wp-load.php 中定義) | require_once ABSPATH . 'wp-admin/includes/plugin.php'; |
include_path:php.ini 中 include_path = ".:/usr/share/php" 只保留必要目錄,減少遍歷次數。./ 前綴:將 include 'lib.php' 改為 include './lib.php',限制查找範圍為當前工作目錄。| 函數 | 失敗行為 | 重複包含 | 適用場景 |
|---|---|---|---|
include | Warning,繼續執行 | 允許重複 | 模板文件、可選組件 |
require | Fatal Error,腳本終止 | 允許重複 | 核心配置、關鍵類庫、必須存在的文件 |
include_once | Warning,繼續執行 | 忽略重複 | 函數庫、類定義、防重複聲明 |
require_once | Fatal Error,腳本終止 | 忽略重複 | 核心類庫、單例初始化、防重複聲明 |
Windows 大小寫不敏感陷阱:
require_once('A.php')和require_once('a.php')在 Windows 下會被視為同一文件(重複包含被忽略),但在 Linux 下是不同文件。統一使用小寫文件名、小寫引用路徑,避免跨平台部署災難。
include_path → 當前腳本目錄 → 相對工作目錄。__DIR__/常量),性能與穩定性雙贏。include/require/_once 變體。include_path、添加 ./ 前綴、開啟 OPcache。