require_once第二次调用返回1,因为其返回值是包含文件执行结果的表达式求值结果;当被包含文件无显式return时,默认返回1(布尔真),且重复调用时仍返回1,故不可用于判断是否首次加载。

require_once 为什么第二次调用返回 1
因为 require_once 不是“返回加载结果”,而是“返回包含文件的执行结果”;当被包含文件末尾没有显式 return 语句时,PHP 默认返回 1(即布尔真)。
这不是 bug,也不是特殊状态码,而是 PHP 对“成功执行无返回值脚本”的统一处理方式 —— 所有不带 return 的 PHP 文件被 include/require 后,表达式求值结果都是 1。
-
require_once第一次执行:加载并运行文件,最后隐式返回1 -
require_once第二次执行:跳过加载(因已记录),但仍会“执行”一个空操作,并按规则返回1 - 这个
1是表达式本身的求值结果,不是函数返回值,更不是“已加载”的标志位
require_once 的返回值不能用来判断是否首次加载
很多人试图用 if (require_once 'foo.php') { ... } 来做条件逻辑,这是危险的。因为无论第几次调用,只要文件存在且可执行,整个表达式恒为真(1)。
- 它无法区分“刚加载”和“已被加载”
- 如果
foo.php最后写了return false;,那require_once表达式就变成false—— 这会让逻辑彻底失控 - 真正判断是否已加载,应查
get_included_files()或用class_exists()/function_exists()等语义化检查
对比 include_once 和 require_once 的返回行为
两者在“重复包含时返回什么”上完全一致:都返回 1(成功执行的默认值)。区别只在错误处理级别:require_once 遇到文件不存在会致命报错(Fatal error),而 include_once 只发警告并继续执行。
立即学习“PHP免费学习笔记(深入)”;
- 它们都不是“返回布尔标记”,而是“包含表达式的求值结果”
- 哪怕写成
$ret = require_once 'x.php';,$ret也几乎总是1,除非被包含文件以return显式结束 - 若被包含文件中有
exit或die,后续代码不执行,但表达式仍返回1(因为退出前已完成执行)
想安全控制加载逻辑,该怎么做
别依赖返回值。用更明确、更可控的方式替代:
- 用
file_exists()+is_readable()提前校验路径有效性 - 用
defined('MY_LIB_LOADED')配合define('MY_LIB_LOADED', true)做手动守卫 - 对类/函数,优先用
class_exists('Foo')或function_exists('bar')判断可用性 - 把初始化逻辑封装进静态方法或单例,由它自己控制是否执行一次
返回 1 是 PHP 解析器层面的行为,不是设计接口。真正需要的是确定性判断,而不是猜表达式返回了什么。



















