CodeIgniter需手动集成zircote/swagger-php^4.9实现Swagger文档生成,因框架本身不支持;scan()路径必须为含.php的绝对目录(非APPPATH拼接),注释须用@OA\前缀、换行闭合且含@OA\Info,JSON响应头必须设Content-Type: application/json,UI中url须为可访问的绝对地址。

CodeIgniter 本身不提供 Swagger 文档生成功能,必须手动集成 zircote/swagger-php 并配合自定义控制器输出 JSON,否则访问 /api/docs 会 404 或返回空对象、TypeError: Failed to fetch。
为什么 swagger\scan() 返回空或报路径错误
根本原因是 scan() 接收的是「含 .php 后缀的绝对文件路径目录」,不是 CodeIgniter 的逻辑路径常量(如 APPPATH)拼接结果。CI3 和 CI4 的目录结构差异进一步放大这个问题:
- CI3 中控制器通常在
application/controllers/,但APPPATH指向application/,所以应传APPPATH . 'controllers'(注意结尾无斜杠) - CI4 中默认是
app/Controllers(首字母大写),而APPPATH . 'Controllers'才对;若用小写的controllers,glob($path . '/*.php')就扫不到任何文件 - 更稳妥做法是用
__DIR__ . '/../app/Controllers'(CI4)或__DIR__ . '/../application/controllers'(CI3),避免依赖常量解析逻辑 - 务必先用
var_dump(glob($path . '/*.php'))验证路径下是否有可读的控制器文件——这是最常被跳过的调试步骤
@OA\ 注释写法必须严格符合 PHP8+ 规范
旧版 @SWG\ 已废弃,且 zircote/swagger-php ^4.9(PHP8.1+ 必选)不支持单行注释或不闭合写法:
- 顶层必须有
@OA\Info或@OA\OpenApi,不能只在方法里写@OA\Get - 注释块必须换行闭合,
/** @OA\Info(title="API") */这种单行写法会被忽略 - 类和方法注释都要存在:控制器类上放
@OA\Info,每个 API 方法上放@OA\Get/@OA\Post等 - 参数类型要显式声明,比如
@OA\Parameter(name="id", in="path", required=true, @OA\Schema(type="integer")),漏掉@OA\Schema会导致字段不显示
JSON 响应头和 UI 加载失败的直接原因
Swagger UI 不是靠 CORS 或网络连通性判断加载成败,而是严格校验响应头中的 Content-Type:
- 生成 JSON 的控制器方法中,必须在
echo $openapi->toJson()前加header('Content-Type: application/json'); - 如果用了 CodeIgniter 的
$this->output->set_content_type(),要确认它没被后续逻辑覆盖(比如某些钩子或输出缓存) - UI 页面中配置的
url必须是可直接浏览器访问的绝对地址,例如https://api.example.com/api/docs.json,不能是相对路径或 localhost 地址(跨域环境会静默失败) - 不要把
swagger.json放到public/下再用 Nginx alias 指向——动态生成的内容必须走 PHP 路由,否则注释变更后不会实时更新
最容易被忽略的是:CI4 的自动路由可能把 /api/docs 当成资源请求拦截了,得在 app/Config/Routes.php 里显式排除或配成 $routes->get('api/docs', 'Docs::index');;还有就是开发时习惯用 die() 调试,一不小心就卡在中间没输出 JSON,UI 就一直转圈。


















