scripts中需写shell命令如"@php scripts/test.php",路径相对项目根目录,PHP脚本须手动require vendor/autoload.php并用__DIR__处理路径,@php确保使用Composer指定PHP版本,参数需脚本内解析。

composer.json 里怎么写 scripts 才能执行 PHP 文件
直接在 scripts 字段里写命令行调用,不是写 PHP 代码。Composer 不会自动加载你的类或执行 PHP 逻辑,它只负责 shell 层面的执行。
- 脚本名(如
dev:clear-cache)是自定义的,运行时用composer dev:clear-cache - 值必须是字符串命令,比如
"php clear.php"或"php -f ./scripts/build.php" - 路径是相对于项目根目录的,别写成
./src/xxx.php却忘了文件实际在scripts/下 - 如果脚本需要加载 Composer 自动加载器,得手动
require 'vendor/autoload.php';—— Composer 不帮你做这事
为什么 php scripts/test.php 报错 “Class not found”
因为默认没引入自动加载器,也没设置当前工作目录。哪怕 test.php 里写了 use App\Something;,也会失败。
- 最简修复:在 PHP 脚本开头加
require __DIR__ . '/vendor/autoload.php'; - 确保脚本里用的是相对路径或
__DIR__,别依赖运行时 pwd(composer run-script可能在任意目录触发) - 避免用
include 'config.php'这种裸路径,改用__DIR__ . '/../config.php' - 错误示例:
"php scripts/deploy.php"→ 脚本里 new 一个 Laravel 的Artisan类?不加载 autoload 就肯定报Class 'Illuminate\Support\Facades\Artisan' not found
scripts 中用 @php 和直接写 php 有啥区别
@php 是 Composer 内置的快捷方式,等价于你配置的 bin-dir 下的 php 可执行文件路径,通常就是当前项目的 PHP 版本(尤其在用 phpbrew、asdf 或多版本环境时更可靠)。
- 推荐写
"@php scripts/migrate.php",而不是"php scripts/migrate.php" - 前者由 Composer 解析并调用正确 PHP,后者走系统 PATH,可能和
composer install用的不是同一个 PHP - 如果你的脚本依赖 ext-redis 或其他扩展,用错 PHP 二进制就直接
PHP Fatal error: Uncaught Error: Call to undefined function redis_connect() -
@php在 Windows 和 Linux 下都有效,不用额外处理 shebang 或 .bat 兼容
如何让脚本支持传参(比如 composer run-script build -- --env=prod)
Composer 原生不解析脚本参数,-- 后面的内容会被原样透传给命令,但你要自己在 PHP 脚本里处理 $argv。
立即学习“PHP免费学习笔记(深入)”;
- 定义 script:
"build": "@php scripts/build.php" - 运行:
composer build -- --env=prod --force - 在
build.php中用array_slice($argv, 1)拿到['--env=prod', '--force'],再 parse - 别指望
$argv[0]是脚本名 —— 在某些环境下它可能是php,所以用basename(__FILE__)更稳 - 如果要用 Symfony Console 风格的选项解析,直接在脚本里 require
symfony/console并初始化Application,别试图让 Composer 做这件事
事情说清了就结束。真正容易被忽略的是:脚本不是“写完就能跑”,它活在 Composer 的执行上下文里,而这个上下文比你想的更薄、更原始。











