应本地生成 vendor 目录后上传:用与线上一致 php 版本运行 composer install --no-dev --optimize-autoloader --no-plugins,禁用符号链接和插件;删掉 composer.json 中 scripts、fxp-asset-plugin、私有 repositories 等共享主机不支持字段;确保 autoload 使用相对路径;上传前清缓存并验证 autoload.php 路径是否为 dir 动态拼接。

共享主机没权限运行 composer 命令怎么办?
绝大多数共享主机禁止执行系统命令,composer 二进制文件直接运行会报 Permission denied 或 Command not found。这不是配置问题,是宿主限制——别浪费时间改 php.ini 或加 PATH。
真正可行的路只有一条:在本地生成完整可部署的 vendor/ 目录,再上传。
- 本地用和线上一致的 PHP 版本(至少主版本相同),比如线上是 PHP 8.1,本地别用 8.3
- 运行
composer install --no-dev --optimize-autoloader,确保不含开发依赖且类映射已固化 - 检查
vendor/autoload.php是否能被正常 require —— 有些主机禁用symlink(),Composer 默认用符号链接方式加载插件,需强制关闭:composer install --no-dev --optimize-autoloader --no-plugins
composer.json 里哪些字段在共享主机上容易失效?
共享主机常禁用函数或限制写入路径,导致某些 Composer 行为静默失败。
-
"scripts"里的post-install-cmd或post-update-cmd:几乎必然失败,主机不支持 exec/fpassthru 等调用外部程序的函数 -
"config": {"fxp-asset-plugin": ...}:已废弃且依赖 Git,共享主机基本不装 Git,删掉 -
"repositories"指向私有 Git 地址:无法克隆,换成 dist 包形式(如"type": "package"+"dist"字段)或直接下载 zip 后手动放vendor/ -
"autoload": {"classmap": ["../some-dir"]}:上级目录可能超出 open_basedir 范围,改成相对路径或全路径(用__DIR__动态拼接更稳)
上传 vendor/ 后仍提示 Class not found?
不是自动加载没生效,大概率是 autoloader 生成时用了绝对路径或符号链接,而共享主机环境不兼容。
- 确认上传后
vendor/autoload.php文件末尾是否包含类似require __DIR__ . '/composer/autoload_real.php';—— 如果是require '/home/user/xxx/vendor/composer/autoload_real.php'这种硬编码绝对路径,说明你在本地生成时没用--apcu-autoloader或没清缓存,删掉vendor/composer/autoload_*.php再重跑composer dump-autoload -o - 检查
vendor/composer/autoload_classmap.php里路径是否全为相对路径(如'Foo\Bar' => __DIR__ . '/..' . '/src/Bar.php'),否则重装前先composer clear-cache - 有些主机禁用
opcache.file_cache,但启用了opcache.enable,会导致类加载器缓存旧的找不到类的判断,临时加一句opcache_reset();到入口脚本开头验证
能不能跳过 vendor/ 直接用 require_once 加载单个包?
可以,但只适合极轻量、无依赖的库(比如一个纯函数工具包)。一旦涉及 PSR-4 自动加载、依赖注入或多个包联动,这条路会迅速失控。
- 找包的「flat release」:去 Packagist 页面点开某个版本,看有没有
zip下载链接,解压后通常含src/和autoload.php,直接require_once 'path/to/autoload.php' - 避免用
require_once 'vendor/autoload.php'的方式加载整个生态 —— 它内部会扫描大量文件,共享主机常因超时或内存限制中断 - 若必须用多个包,优先选提供
single-file分发的(如monolog/monolog有Monolog.php入口),而不是靠 Composer 自动发现
最麻烦的从来不是怎么传文件,而是弄清哪一行 require 在哪一刻因为哪个被禁函数而静默失败 —— 打开 display_errors、设好 error_log 路径,比反复上传 vendor 更省时间。










