页面突然报 Cannot redeclare class 之类的错误,翻译过来是类或者函数被重复定义了。十有八九是同一个文件被包含了两次,这时候就该 require_once 出场。
四个包含语句的区别
- include:找不到文件只给 warning,脚本继续往下跑
- require:找不到文件直接 fatal error,脚本停住
- include_once:行为同 include,但同一文件只包含一次
- require_once:行为同 require,且同一文件只加载一次
require_once 的定位很明确:配置文件、类定义、公共函数库这类只能加载一遍的东西。函数和类重复声明会直接报错,用它就不会踩这个坑。
路径问题最常见
require_once __DIR__ . '/config.php';写相对路径时,PHP 是按当前脚本所在目录加上 include_path 去找的,目录一深,被包含的文件再去包含别人,路径就容易乱。用 __DIR__ 拼上当前文件所在目录,整个项目挪到哪一层都不怕。Windows 下写正斜杠没问题,反斜杠反而可能被当成转义符。
性能上要不要纠结
_once 系列要维护一张已加载文件的清单,每次包含前先查一遍,文件特别多的老项目里开销能测出来,一般业务里可以忽略。真在意的话,现代 PHP 项目都走 composer 的自动加载,根本不手写这些语句了。
取舍建议:类库、配置、函数库用 require_once,模板片段、视图文件用 include 就够了,缺一块也不至于停整个页面。被包含的文件尽量只定义、少执行,混着写最容易出重复定义的怪问题。