@php 是 Composer 的语法糖,仅在 composer.json 的 scripts 字段中有效,非系统命令,故 shell 中直接执行会报“Command not found”;路径须相对 composer.json 目录。

scripts 里用 @php 调用 PHP 文件,为什么报错“Command not found”
因为 @php 不是系统命令,而是 Composer 自己的语法糖,只在 composer.json 的 scripts 字段里有效,不能直接在 shell 里敲 @php xxx.php 运行。
常见错误现象:sh: @php: command not found 或脚本根本没执行、静默失败。
-
@php必须写在composer.json的scripts下,例如:"dev:check": "@php scripts/check.php" - 路径必须是相对
composer.json所在目录的(不是当前 shell 工作目录) - PHP 文件开头不需要
#!/usr/bin/env php,但建议加并确保有可执行权限(Linux/macOS) - Windows 下
@php也能工作,Composer 会自动映射到本地 PHP 可执行文件
想在 scripts 里传参数给 PHP 脚本,怎么写
Composer 默认不透传参数,@php script.php arg1 arg2 中的 arg1、arg2 不会进 $argv —— 除非你显式启用参数透传。
- 使用
php命令代替@php:例如"dev:run": "php scripts/tool.php --verbose" - 或者用
@php+exec绕过(不推荐):"dev:run": "@php -r \"exec('php scripts/tool.php --verbose');\"" -
@php本质是让 Composer 自己调用 PHP 解释器,它不解析后续参数;而php是调用系统命令,参数原样传递 - 如果脚本需交互(如
readline()),用php更可靠;@php在某些环境可能关闭 STDIN
scripts 中执行 PHP 脚本时,autoload 没生效怎么办
因为 @php 或 php 直接运行 PHP 文件,不会自动加载 Composer 的 autoloader —— 你得自己 require。
- 在 PHP 脚本头部加上:
require __DIR__ . '/vendor/autoload.php';(路径按实际调整) - 别依赖
vendor/autoload.php在根目录,有些项目把vendor放在子目录(比如app/vendor),这时要算对相对路径 - 如果脚本本身在
vendor/bin/下或由bin/符号链接调用,autoload 通常已就绪;但scripts里手写的路径不是这样 - 可以用
getcwd()打印当前工作目录,确认是不是你以为的那个目录 —— Composer 执行 scripts 时工作目录是composer.json所在位置
用 php -S 启动内置服务器时,@php 会卡住不退出
这是典型阻塞行为:@php -S localhost:8000 router.php 启动的是长进程,而 Composer 的 scripts 机制默认等待命令结束才继续。结果就是终端卡住、CI 构建超时、Ctrl+C 都没反应。
- 改用
php -S并后台运行:"serve": "php -S localhost:8000 router.php > /dev/null 2>&1 & echo $! > .server.pid" - 更稳妥的做法是不用
scripts启服务,改用 Makefile 或专用 dev-server 包(如symfony/cli) -
@php不适合跑守护进程类任务;它设计初衷是短时、幂等、可预期退出的操作 - 如果真要在 CI 中测试 HTTP 接口,建议用一次性请求 + timeout 控制,而不是长期占着一个 server 进程
Composer 的 @php 看似方便,实则边界很窄:它只在 scripts 上下文里翻译成 PHP 路径,不接管进程模型、不处理参数、不自动引入 autoloader。多数“不工作”的问题,其实是因为把它当成了通用 shell 替代品。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











