90%的“Permission denied”是因目录属主非当前用户所致,需定位报错路径→查ls -ld归属→用sudo chown -R $USER:$USER修复vendor/、composer.lock及缓存目录,禁用chmod 777和sudo composer install。

90% 的 Permission denied 不是权限位不够,而是目录属主(owner)不是当前用户——vendor/、composer.lock 或 ~/.composer 被 sudo composer install 污染过,修复只需归还所有权,不是 chmod 也不是重装 PHP。
报错路径一出现,立刻定位问题目录
终端错误里带完整路径的那一行就是唯一线索,别猜。比如:
-
file_put_contents(/home/alex/myapp/vendor/autoload.php): Permission denied→ 锁定vendor/ -
Could not write to /home/alex/myapp/composer.lock→ 锁定composer.lock -
Writing cache file ~/.composer/cache/repo/https---packagist.org/→ 锁定全局缓存目录
马上执行这三行确认归属:
ls -ld vendor/ ls -ld composer.lock ls -ld $(composer config --global cache-dir)
只要任意一行输出第三列(owner)不是 $(whoami),就是所有权错配。
chown 是解药,chmod -R 777 是毒药
chmod 控制“能不能读写”,chown 才决定“这东西归不归你”。误用 chmod -R 777 会触发 CI 拒收、Git 提示 ownership changed、后续 dump-autoload 静默失败。
- 项目内修复:
sudo chown -R $USER:$USER vendor/ composer.lock(注意末尾斜杠,否则子目录可能漏掉) - 全局缓存修复:
sudo chown -R $USER:$USER $(composer config --global cache-dir) - 整个
~/.composer都被 root 占了:sudo chown -R $USER:$USER ~/.composer,再加固:chmod -R u+rw ~/.composer
sudo 这里只用于临时提权跑 chown,不是让你去跑 sudo composer install——后者才是污染源头。
Docker / CI / Windows 下的隐性坑
这些环境不报错在明面,但一样卡住:
- Docker:宿主机 UID 是 1000,容器默认用 UID 0(root),挂载卷后文件不可写 → 启动时加
-u $(id -u):$(id -g),或修复时用数字 UID:sudo chown -R 1000:1000 ~/.composer - CI(如 GitHub Actions):默认非 root 用户 → 开头加
mkdir -p .composer-cache && chmod 700 .composer-cache,再设COMPOSER_CACHE_DIR="$PWD/.composer-cache" - Windows:
%APPDATA%\Roaming\Composer\Cache报Access is denied→ 管理员 PowerShell 执行:icacls "$env:APPDATA\Roaming\Composer\Cache" /grant "$env:USERNAME:(OI)(CI)F" /t
全局命令找不到(如 laravel)怎么查
装成功但输 laravel 提示 command not found,大概率是 ~/.composer/vendor/bin 没进 $PATH,或者该路径本身权限受限:
- 确认 bin 目录位置:
composer config -g bin-dir(默认是~/.composer/vendor/bin) - 检查归属:
ls -ld $(composer config -g bin-dir),若属主不是你,执行:sudo chown -R $USER:$USER $(composer config -g bin-dir) - 加进环境变量:
echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc - 更稳妥方案:
mkdir -p ~/bin && composer config -g bin-dir ~/bin && echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc && source ~/.zshrc
所有修复都必须在删掉污染产物(vendor/、composer.lock)之后立即执行;否则新生成的文件仍会继承错误属主,白修一次。











