require两次同一文件会重复执行,导致变量重赋值、函数重复声明报错;require_once通过路径归一化哈希表避免重复加载,但路径不等价仍会重复,且不能解决作用域隔离问题。

require 两次同一个文件会重复执行
PHP 不会阻止你写两次 require,它会照单全收、原样执行——第二次 require 仍会读入、解析、执行目标文件,和第一次完全一样。
这意味着:变量会被重新赋值、函数会被重复声明(触发 Fatal error: Cannot redeclare function_name())、类定义冲突、数据库连接可能被覆盖或重复建立。
- 不是“跳过”,而是“真·再跑一遍”
- 不检查是否已加载,也不维护已包含列表
- 即使在同一个脚本里连续写两行
require 'config.php'; require 'config.php';,也会执行两次
require_once 才真正防止重复包含
require_once 的核心行为是运行前查表:PHP 内部维护一个已包含文件路径的哈希表,每次调用时先 normalize 路径(处理 ./、../、符号链接等),再查是否已存在。命中则跳过,否则加载并记录。
但要注意:路径字符串必须逻辑等价,否则仍会被视为不同文件。比如:
require_once 'config.php';-
require_once './config.php';→ 很可能被当作另一个文件,再次加载 -
require_once __DIR__ . '/config.php';和require_once 'config.php';在某些 PHP 版本中也可能不等价
所以推荐统一用 __DIR__ 或 dirname(__FILE__) 拼接绝对路径,避免歧义。
require 两次导致函数重复定义的典型错误
最常踩的坑就是把含函数定义的文件(如 helpers.php)用 require 多次引入。例如:
<?php require 'helpers.php'; // 定义了 function format_date() { ... }
require 'helpers.php'; // ⚠️ 再次 require → Fatal error
?>
这种错误在模块化不清晰、或通过条件分支多次引入时极易发生。而 require_once 能直接拦截该问题,但前提是所有调用都用 _once 版本——混用 require 和 require_once 仍会触发重复(因为 require 不登记,require_once 查不到记录)。
性能与语义:require_once 并非万能
require_once 确实多了路径归一化 + 哈希查找开销,但现代 PHP(7.4+)对此优化极好,单次开销可忽略。真正影响性能的是大量小文件 + 频繁 _once 判断(比如在循环内调用),这时应重构为一次引入、多次使用。
更关键的是语义误用:有人以为 require_once 能“安全地在任意位置调用”,却忽略了它只保证“文件级唯一”,不保证“变量/函数作用域隔离”。例如在函数体内 require_once 一个定义全局变量的配置文件,第二次调用该函数时变量已不存在(因为文件没重载,但变量未重新声明)——这是常见于配置热加载失败的根源。
真正容易被忽略的点是:文件是否该被多次执行,取决于它的内容性质;而不是“用不用 _once”这个开关能自动解决所有问题。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











