Composer scripts 不自动加载项目类,PHP 脚本中 new 类必报 Class not found;需在脚本首行显式 require DIR . '/vendor/autoload.php'(路径依实际调整),并用 @php 调用、-v 参数调试,避免工作目录依赖。

Composer 的 scripts 不会自动加载项目类,PHP 脚本里直接 new MyClass() 必报 Class not found;它也不是钩子系统,只是按名触发的命令列表——名字错、位置错、没显式引入 autoloader,脚本就静默失效。
post-install-cmd 为什么有时根本不运行
这不是配置失效,而是 Composer 的执行条件被忽略了:
-
post-install-cmd只在composer install实际执行了依赖安装时才触发;如果vendor/已存在且composer.lock没变,Composer 会跳过安装流程,也就不会触发该钩子 -
composer require xxx属于update流程,只走post-update-cmd,不走post-install-cmd - 加了
--no-scripts参数(CI 中常见)或环境变量COMPOSER_NO_INTERACTION=1也会跳过 - 脚本名拼写错误(比如
post-install-cmd写成postinstall-cmd或大小写混用)会导致完全不识别
PHP 脚本里 new 类报 Class not found 怎么办
Composer 执行 scripts 时不自动引入 vendor/autoload.php,这是设计使然,不是 bug。解决方式非常具体:
- 在 PHP 脚本第一行写
require __DIR__ . '/vendor/autoload.php';—— 注意是__DIR__,不是getcwd();如果脚本在scripts/目录下,路径要改成dirname(__DIR__) . '/vendor/autoload.php' - 别用
include_once 'vendor/autoload.php',相对路径极易因工作目录变化而失败 - 若用类方法回调(如
"MyClass::run"),必须确保该类已通过autoload或autoload-dev正确注册,且方法是public static - 不推荐在脚本里手动
require单个类文件,容易漏依赖或与 PSR-4 冲突
怎么安全调用 PHP 脚本并控制执行顺序
避免 shell 片段耦合、跨平台失败和权限问题,关键在写法和调用方式:
立即学习“PHP免费学习笔记(深入)”;
- 用数组格式声明命令:
"post-update-cmd": ["@php scripts/clear-cache.php"],比字符串"php scripts/clear-cache.php"更可靠,避免 shell 解析歧义 - 优先用
@php而非系统php,它自动匹配当前运行 Composer 的 PHP 可执行路径,防止版本错乱 - 多个命令需强依赖顺序时,用
&&显式串联:"@php build.php && @php deploy.php";否则默认每条独立执行,前一条失败不影响后一条 - 脚本文件本身不要加
#!/usr/bin/env php头,Composer 不走 shebang,会直接报错
自定义脚本名(如 dev:build)怎么触发和调试
这类名字不会自动绑定任何事件,必须手动调用,且调试信息极依赖细节:
- 运行方式只能是
composer run dev:build(新版)或composer run-script dev:build(旧版兼容);composer dev:build是无效命令 - 验证是否注册成功:运行
composer run -l查看所有可执行脚本列表,没出现说明scripts不在根composer.json,或 JSON 格式非法 - 调试必加
-v:composer run dev:build -v,能看到Executing script ...日志;没这行,说明根本没读到该脚本 - 脚本中不要依赖未声明的全局命令(如
npm),建议用vendor/bin/npm或先which npm判断是否存在
最易被忽略的是:脚本执行时的工作目录虽通常是项目根,但某些 CI 环境或 IDE 会覆盖 getcwd(),所以任何资源路径(如读取 .env、写日志)都应基于 __DIR__ 或 dirname(__FILE__) 定位,而不是相对路径或 ./ 开头的硬编码。



















