页面突然报 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 就够了,缺一块也不至于停整个页面。被包含的文件尽量只定义、少执行,混着写最容易出重复定义的怪问题。