composer拉取包后文件权限错乱的根源是umask值影响文件创建,默认导致php文件为600、目录为700;正确解法是在post-autoload-dump中按类型精确设权:先ugo-w,再644 php文件、755 bin脚本、755目录,或在ci中改用非root用户执行。

Composer 拉取包后文件权限错乱,不是 Composer 的 bug,而是你没关掉 umask 或没配好 post-autoload-dump 脚本的执行上下文。
为什么 vendor 里一堆 .php 文件变成 600 或 700?
根本原因是:Composer 在执行 install/update 时,会以当前 shell 的 umask 值创建文件(比如 umask 0077 → 新文件默认 600,目录 700)。尤其在 CI 环境或用 root/sudo 运行时,umask 往往更严格。
常见错误现象:composer install 后 vendor/autoload.php 权限是 -rw-------,Web 服务器直接报 “failed to open stream: Permission denied”。
- 不要在
composer.json的scripts里直接写chmod -R 755 vendor/—— 这会把所有文件都设成可执行,PHP 文件被当成二进制执行可能触发 Suhosin 或 SELinux 拒绝 - 不要用
find vendor -type f -exec chmod 644 {} ;—— 它会误改bin/下真正需要 +x 的脚本 - 真正要区分的是:普通 PHP 文件(644)、可执行脚本(755)、目录(755)
post-autoload-dump 脚本怎么安全修权限?
这个钩子在 autoloader 生成后触发,时机合适,且只在本地开发或部署阶段运行,不影响 packagist 分发逻辑。
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
在 composer.json 中添加:
"scripts": {
"post-autoload-dump": [
"chmod -R ugo-w vendor/",
"find vendor/ -type f -name "*.php" -exec chmod 644 {} \;",
"find vendor/ -type f -path "*/bin/*" -exec chmod 755 {} \;",
"find vendor/ -type d -exec chmod 755 {} \;"
]
}
注意点:
-
ugo-w先去掉所有人的写权限,避免后续 chmod 漏掉某些文件 - 必须先设
*.php为 644,再单独给bin/下文件加x,顺序反了会导致 PHP 文件也被设成 755 - 别用
chmod -R 644 vendor/—— 目录不能是 644,否则opendir()失败
CI/CD 环境下更推荐的解法:不修权限,换执行用户
在 GitHub Actions、GitLab CI 或 Docker 构建中,硬修权限容易和缓存层冲突(比如 vendor 缓存后权限固化),不如从源头控制创建者。
- Dockerfile 里别用
USER root跑composer install,改用非特权用户:RUN addgroup -g 1001 -f www && adduser -S phpuser -u 1001,再USER phpuser - GitHub Actions 中,在
steps里加run: composer install前插入:shell: bash -c 'umask 0022 && $0 $@' - 如果必须用 root(如某些私有仓库需 ssh-agent),记得
chown -R www-data:www-data vendor/而不是只改权限
最易被忽略的一点:有些私有包的 composer.json 自带 post-install-cmd,它可能在你的脚本之前就生成了带错误权限的文件——务必检查所有依赖包的 scripts 字段,必要时 fork 并 patch。










