require_once在文件缺失或语法错误时抛出致命错误并中断脚本,include_once仅触发警告且继续执行;两者均确保单次加载,但适用场景不同:前者用于强制依赖,后者用于可选模块。

require_once 会中断脚本,include_once 不会
当目标文件不存在或语法错误时,require_once 抛出 E_COMPILE_ERROR 致命错误,后续代码完全不执行;include_once 只触发 E_WARNING,脚本继续往下跑。比如:
include_once 'missing.php'; echo 'still runs'; // 这行会输出
require_once 'missing.php'; echo 'never reaches here'; // 这行不会执行
这决定了它们的使用场景:配置文件、核心类定义必须用 require_once,否则缺了就该挂;而可选功能模块(如第三方统计埋点)、兜底逻辑可用 include_once 保底。
两者都只加载一次,但检查时机和开销略有差异
include_once 和 require_once 都会查 PHP 内部的已加载文件列表(realpath cache),确认路径是否已存在。这个检查本身有微小开销,但对现代 PHP(7.4+)影响几乎可忽略。
- 路径必须完全一致才会被识别为“已加载”——
./config.php和config.php被视为两个文件 - 软链接、符号链接可能导致 realpath 不同,从而绕过 _once 判断
- CLI 模式下每次请求是独立进程,_once 的“一次”仅限单次请求生命周期
require_once 更适合强制依赖,include_once 更适合柔性包含
语义上,require_once 表达的是“这个文件必须存在且正确,否则整个流程无意义”;include_once 更偏向“尝试加载,失败也无所谓”。实际项目中常见模式:
立即学习“PHP免费学习笔记(深入)”;
- 框架自动加载器一般用
require_once加载核心类,避免类未定义 fatal error - 插件系统里动态 include 第三方模块时,常用
include_once+file_exists()做前置判断,防止警告污染日志 - 在函数内动态包含模板片段(如
include_once $tpl_path),若路径不可控,优先选include_once防止崩掉主流程
别忽略 realpath 缓存和 open_basedir 限制
PHP 的 _once 判断依赖 realpath() 结果,而该结果受以下因素影响:
-
opcache.enable开启时,realpath cache 默认启用,但缓存时间由opcache.revalidate_freq控制(默认 2 秒) - 如果启用了
open_basedir,而被包含路径超出限制范围,require_once和include_once都会失败,但错误类型不同:require_once是 fatal error,include_once是 warning + false 返回值 - Windows 下大小写不敏感,Linux 下敏感——同一路径大小写混用可能意外绕过 _once
最常被忽略的一点:_once 的“一次”只针对当前请求中的绝对路径,不跨请求、不跨进程、也不跨 CLI 脚本实例。如果你在循环里反复调用,它确实只加载一次;但如果你在多个并发请求里各自调用,每个请求都会独立走一遍检查逻辑。



















