slim 4 需显式安装 slim/slim:^4.13 及 slim/psr7:^1.6,统一约束 psr/http-message:^1.0,配置 psr-4 自动加载,并在 alpine 容器中用 su-exec 固定用户执行 composer install。

composer install slim4 时提示 “package not found”
Slim 4 不再是 slim/slim 单一包,而是拆成了核心 + PSR 接口 + 容器适配器。直接 composer require slim/slim 会失败(尤其在 PHP 8+ 或较新 Composer 版本下)。
- 必须显式指定版本:运行
composer require slim/slim:^4.13(当前稳定版,避免用^4.0触发旧版兼容问题) - 如果项目已启用
minimum-stability: stable,且未设prefer-stable: true,某些子依赖(如slim/psr7)可能被误判为“不稳定”,需补装:composer require slim/psr7:^1.6 - 别跳过
autoload配置 —— Slim 4 默认不自动注册 autoloader,得确保composer.json里有"autoload": {"psr-4": {"App\": "src/"}},否则new AppApp()会报类找不到
微服务场景下 slim 与 composer 的 autoloader 冲突
多个微服务共用一个 vendor 目录(比如通过 symlink 或共享 volume),或使用 composer install --no-autoloader 后手动加载,极易触发 Class 'PsrHttpMessageServerRequestInterface' not found。
- 根本原因是 PSR 接口包(
psr/http-message)被不同服务以不同版本 require,Composer 的 autoloader 只加载第一个匹配的,后续覆盖失效 - 解法不是删 vendor,而是统一约束:所有服务的
composer.json必须声明相同版本的psr/http-message:^1.0和psr/http-server-handler:^1.0 - 验证是否生效:执行
composer show psr/http-message,输出应为1.0.1或1.1.0,绝不能是2.0(Slim 4 不兼容 PSR-17 v2)
slim4 在 docker-compose 微服务中 composer install 失败
常见于 Alpine 基础镜像(如 php:8.2-alpine)构建阶段,报错类似 file_put_contents(/var/www/vendor/composer/installed.json): failed to open stream: Permission denied。
- 不是权限没设对,而是 Alpine 的
composer二进制默认以 root 运行,但容器内工作目录属主是www-data,导致写入失败 - 不要用
chown -R www-data:www-data /var/www暴力修复 —— 下次composer install仍会因用户切换失败 - 正确做法是在 Dockerfile 中固定用户上下文:
RUN apk add --no-cache su-exec && composer install --no-dev --optimize-autoloader && chown -R www-data:www-data /var/www/vendor,然后用su-exec www-data php -S启动
为什么 slim4 的 composer require 要带 ^4.13 而不是 ^4.0
因为 Slim 4.0 ~ 4.8 使用的是 slim/psr7 作为 HTTP 消息实现,而 4.9+ 切换到了 nyholm/psr7 + nyholm/psr7-server,两者 API 表面一致,底层行为差异极大。
-
nyholm/psr7默认禁用全局 stream wrapper(php://input读取会空),微服务间 JSON body 传递直接丢数据 - 若你用了
slim/psr7的ServerRequest::getParsedBody(),升级到 4.9+ 后必须加中间件new NyholmPsr7ServerServerRequestCreator(),否则解析失败 - 所以生产环境务必锁死小版本:用
^4.13(已内置兼容层)比赌大版本兼容更稳
composer require 命令,但微服务之间只要有一个服务用了 psr/http-message:2.0,整个链路的请求解析就可能静默失败。










