Composer 2.x 已彻底移除 use-include-path 配置,设了也无效;正确做法是用 autoload.files 或 autoload.classmap 显式声明,或清空 include_path 确保加载一致性。

别设了,use-include-path 在 Composer 2.x 中已彻底移除,设了也无效;即使你用的是 Composer 1.x,它也不是“配置自动加载”的正路,而是个过渡补丁。
composer.json 里写 "use-include-path": true 没用(Composer 2+)
从 Composer 2.0 开始,"config": { "use-include-path": true } 这个字段被完全删除。你加进去,composer install 或 composer dump-autoload 都会忽略它,也不会报错——只是安静地失效。
- Composer 2.x 默认行为就是:自动加载只走 PSR-4/PSR-0/classmap/files 映射,完全不查
include_path - 如果你在 Composer 2 环境下看到旧文档说“加这个就能用
require 'Foo.php'”,那文档已经过期至少三年 - 验证方法:执行
composer show --platform看 Composer 版本;再检查生成的vendor/autoload.php,里面不会有set_include_path()调用
为什么老项目还能“看起来生效”?
常见错觉来源:
- 你其实用的是 Composer 1.10.x(比如某些 Docker 镜像或 CI 环境没升级),它还支持该配置,但已是维护末期
- 你以为是
use-include-path起作用,其实是手动在入口文件写了set_include_path(),或者用了"autoload": { "files": [...] } - 某些私有 fork 或自定义安装器硬塞了该逻辑,但这不属于官方 Composer 行为
关键点:use-include-path 从来就不是 Composer 自动加载的核心机制,它只是在 vendor/autoload.php 开头插入一行 set_include_path(),且仅影响后续裸 require 调用,对 new Class() 或命名空间调用无直接作用。
真正要解决“旧 require 语句找不到文件”,该怎么做?
不要碰 include_path,它不可控、难调试、性能差。优先走 Composer 原生支持的路径:
- 如果那些是纯函数文件(如
vendor/pear/net_url2/Net/URL2.php),在composer.json里加:"autoload": { "files": [ "vendor/pear/net_url2/Net/URL2.php" ] }然后运行composer dump-autoload—— 它会在每次请求时require_once一次,且路径相对于composer.json,OPcache 可缓存 - 如果是类文件但没命名空间,又必须兼容旧写法,用
classmap:"autoload": { "classmap": ["vendor/legacy/"] }然后composer dump-autoload,Composer 会扫描并建立文件路径映射 - 绝对避免在代码里用
ini_set('include_path', ...)—— 它会覆盖 SAPI 层级的全局设置,PHP-FPM 下可能让其他扩展失效
清空 include_path 是更安全的默认操作
很多“类找不到”问题,根源其实是裸 require 'SomeClass.php' 误触了系统 include_path 里的旧版本文件(比如 /usr/share/php 下的 PEAR 包)。这时候最干净的做法是主动清空:
- 在项目入口(如
public/index.php)第一行加:set_include_path(''); - 确保所有依赖都通过 Composer autoload 加载,不给歧义留余地
- 配合
"config": { "classmap-authoritative": true }和composer dump-autoload -o,能进一步杜绝运行时文件探测开销
复杂点在于:use-include-path 听起来像“开启功能”,实则是把加载逻辑从明确的映射推回模糊的路径搜索——这种退化设计,现在连 Composer 自己都放弃了。你真正该花时间的,是把那几处 require 'xxx.php' 改成命名空间引用,或者收进 files 列表。











