Composer 如何使用脚本生成文档

开门见山,先说核心结论:Composer 本身并不直接生成文档,但它提供了一个强大的“自动化开关”——通过配置 scripts 项,你可以轻松调用 phpDocumentor 这类外部工具来完成任务。 整个过程听起来简单,但成败的关键往往藏在细节里:脚本定义是否准确绑定到了正确的生命周期事件?执行环境是否已经备齐了所有依赖?
如何在 composer.json 中定义文档生成脚本
一切都要从 composer.json 文件里的 "scripts" 区域说起。这里是你定义自动化命令的“控制中心”。一个实用的建议是,使用像 "docs" 或 "generate-docs" 这样语义清晰的自定义命令名,可以有效避免与 Composer 的内置命令发生冲突。
那么,具体怎么写呢?脚本值可以是字符串数组,也可以是单个字符串,既支持直接的 shell 命令,也支持调用 PHP 类方法。来看几个典型的配置方案:
- 基础版:用 shell 命令调用 phpDocumentor –
"docs": ["phpdoc -d src -t docs/api"] - 推荐版:通过 vendor 二进制确保环境一致性 –
"docs": ["vendor/bin/phpdoc -d src -t docs/api"] - 多步骤版:先清理旧文档,再生成新文档 –
"docs": ["rm -rf docs/api", "vendor/bin/phpdoc -d src -t docs/api"] - 高级版:使用 PHP 回调函数 –
"docs": ["My\Doc\Generator::run"](前提是确保这个类和方法确实存在且可访问)
为什么 composer run docs 报错“command not found”
配置写好了,兴冲冲地运行 composer run docs,结果终端却冷冷地抛出一句“command not found”。别急着怀疑 Composer,问题十有八九出在执行上下文上。
这时候,你需要按顺序排查以下几个常见陷阱:
- 工具安装了吗? 首先确认 phpDocumentor 是否已经作为开发依赖安装:
composer require --dev phpdocumentor/phpdocumentor。 - 路径对了吗? 检查
vendor/bin/phpdoc这个可执行文件是否存在(Windows 用户请注意,对应的可能是phpdoc.bat)。 - 权限和环境呢? 避免使用
sudo composer run docs,因为 root 用户的环境可能找不到当前项目的vendor目录。此外,一些共享主机会禁用exec()函数,这会导致无论是 shell 命令还是 PHP 回调都会失败。 - 路径里有空格? 如果目录路径包含空格,在 shell 模式下很容易解析错误。这种情况下,改用 PHP 脚本进行封装会更稳妥。
如何让文档生成自动触发(如 composer install 后)
手动执行命令还不够自动化?Composer 的事件钩子可以帮你。但这里有个重要的原则需要把握:文档生成本质上属于开发阶段的行为,不应该绑定到 post-install-cmd 这类与生产部署相关的事件上,否则可能会拖慢线上部署流程,甚至导致失败。
比较安全的做法是,将文档生成绑定到 post-update-cmd 事件上,这样只有在开发者主动更新依赖后才会触发:
"post-update-cmd": ["@docs"]
注意这里的 @docs 符号,它表示复用之前已经定义好的 docs 脚本,避免了命令的重复书写。当然,如果你坚持希望每次 composer install 后都运行,也可以显式添加 "post-install-cmd": ["@docs"],只是通常不推荐这么做。
话说回来,在 CI/CD 流水线中,更可靠的做法往往是将文档生成作为一个独立的 pipeline 步骤,而不是完全依赖 Composer 的事件机制。
最后,不得不提那些真正让人头疼的“魔鬼细节”:跨平台兼容性问题。比如,脚本里的 rm -rf 命令在 Windows 上会失效;vendor/bin 下的路径可能因 PHP 版本不同而指向不同的位置;还有,phpDocumentor v3 要求 PHP 版本必须在 8.1 以上。这些细节如果不经过手动验证,仅凭配置文件里的几行脚本,是很难顺利跑起来的。
