Laravel 5.5 中 Swagger 不能开箱即用,必须借助 darkaonline/swagger-lume;因 zircote/swagger-php 仅生成 JSON,不提供路由、中间件和 UI 集成,硬套会导致 404 或非 JSON 响应错误,而 swagger-lume 专为 Lumen 设计但兼容 Laravel 5.5,通过原生 PHP 输出 HTML 并复用 JSON 生成逻辑,需正确配置 paths、version 字段、路由位置及注解语法(@OA\Get 等),否则文档空白或 500。

Swagger 在 Laravel 5.5 中不能直接开箱即用,必须借助第三方包 darkaonline/swagger-lume(原 swagger-php + lumen-swagger 衍生版),官方 swagger-api/swagger-ui 本身不绑定框架,需手动集成路由与资源分发。
为什么不用 zircote/swagger-php 直接配合 Laravel?
Laravel 5.5 的服务容器和响应机制与 Swagger UI 的静态资源加载、JSON Schema 输出路径不匹配;zircote/swagger-php 只负责从 PHP 注解生成 JSON,不提供路由、中间件、前端界面。硬套会导致 404 或 Response not JSON 错误。
- 注解解析后需输出到固定路径(如
/docs/json),但 Laravel 默认不暴露 public 下的非静态资源 - Swagger UI 页面需通过 Laravel 路由渲染,否则跨域或 base-url 错误
-
Route::view()加载本地index.html时,内部 JS 请求的swagger.json往往 404,因未配置对应 API 路由
darkaonline/swagger-lume 的适配要点
该包专为 Lumen 设计,但兼容 Laravel 5.5,关键在于绕过 Laravel 的 view 编译机制,用原生 PHP 输出 HTML,并复用其内置的 JSON 生成逻辑。
- 安装后必须发布资源:
php artisan vendor:publish --provider="Lume\Swagger\SwaggerServiceProvider" - 配置文件
config/swagger.php中'paths' => ['app/Http/Controllers']必须包含你写注解的实际控制器路径 - 注解中的
@OA\Info和@OA\PathItem必须有version字段,否则 UI 加载失败并静默退出 - 路由注册必须放在
routes/web.php最底部,避免被其他中间件拦截(尤其 Auth 或 CORS 中间件)
控制器里写注解的常见翻车点
Swagger 5.x 注解语法(OpenAPI 3.0)在 Laravel 5.5 上需严格匹配 zircote/swagger-php 3.x 版本,不支持 @SWG\ 前缀(那是旧版 Swagger 2.0)。
- 错误写法:
@SWG\Get(path="/api/users")→ 会忽略,不报错但不出现在文档中 - 正确写法:
@OA\Get(path="/api/users"),且必须引入命名空间:use OpenApi\Annotations as OA; - 参数必须显式声明
@OA\Parameter,不能只靠Request类型提示自动推导 - 响应体若用
@OA\JsonContent,ref必须指向已定义的@OA\Schema,不能直接写type="object"混用
访问 /api/documentation 时空白或 500 的排查顺序
不是缓存问题,而是 JSON 生成链断裂。优先检查日志里是否有 ReflectionException 或 Class not found。
- 执行
php artisan swagger-lume:generate,看是否报Could not process class XXX—— 通常是控制器没 use 对应 Request 类或 DTO - 打开
storage/logs/laravel.log,搜索swagger,90% 是注解里引用了不存在的 schema 名称 - 确认
APP_DEBUG=true,否则错误被吞掉,页面只显示空白 - 浏览器 Network 面板查看
/api/documentation加载的swagger-ui-bundle.js是否 404 —— 若是,说明public/vendor/swagger-lume未成功发布
最麻烦的是注解嵌套层级:一个 @OA\Post 里混用 @OA\Parameter、@OA\RequestBody、@OA\Response 时,少一个 name 或 in 就导致整个接口消失,且无提示。


















