PHP 提供四種檔案引入語句:include、include_once、require、require_once。雖然功能相似,但在「多子類繼承同一父類」的場景下,require 會觸發 Cannot redeclare class 致命錯誤,而 require_once 則能完美避開。
<?php
// AbstractClass.php
abstract class AbstractClass {}
<?php
// RequireClassA.php
require 'AbstractClass.php';
class RequireClassA extends AbstractClass {}
<?php
// RequireClassB.php
require 'AbstractClass.php';
class RequireClassB extends AbstractClass {}
<?php
// test.php
require_once 'RequireClassB.php';
require_once 'RequireClassA.php';
$A = new RequireClassA();
$B = new RequireClassB();
PHP Fatal error: Cannot redeclare class AbstractClass in /path/to/AbstractClass.php on line 2
require 就會**無條件編譯執行**該檔案。test.php 時,依序編譯 RequireClassB.php(載入一次 AbstractClass)、RequireClassA.php(再次載入 AbstractClass),導致類重複定義。include 同樣會重複執行,僅差別在失敗時產生 Warning 而非 Fatal error,但重複定義類的錯誤本質相同,同樣會導致 Cannot redeclare class。
| 場景 | 推薦語句 | 理由 |
|---|---|---|
| 類/介面/特徵定義檔案 | require_once | 防止重複定義,缺少檔案屬嚴重錯誤應中止 |
| 配置檔、模板檔(可重複引入) | include | 允許多次引入,失敗不中斷主流程 |
| 效能極度敏感、確定無重複引入 | require | 省去檢查開銷,但風險自負 |
使用 PSR-4 自動載入器(vendor/autoload.php)徹底消除手動 require,由類映射表按需載入,從根源解決重複引入問題:
// composer.json
{
"autoload": {
"psr-4": {
"App\\": "src/"
}
}
}
執行 composer dump-autoload 後,專案中任何地方直接 use App\AbstractClass; 即可,無需手動引入。
require 在類繼承鏈中極易引發重複定義錯誤,require_once 以微小效能換取穩健性。現代 PHP 專案應全面採用 Composer 自動載入,將檔案引入交給成熟的自動載入器處理,專注於業務邏輯開發。