CodeIgniter4创建RESTful API遇命名空间重复404错误求助
CodeIgniter4 RESTful API 404错误排查与解决
问题现象
使用CodeIgniter4搭建RESTful API时,通过$routes->resource()定义type-blood路由,访问http://localhost:8080/type-blood返回404错误,错误信息显示控制器路径重复:
{ "title": "CodeIgniter\\Exceptions\\PageNotFoundException", "type": "CodeIgniter\\Exceptions\\PageNotFoundException", "code": 404, "message": "Controller or its method is not found: \\App\\Controllers\\App\\Controllers\\TypeBloodController::index", "file": "/home/faker/CodeIgniter/c4/vendor/codeigniter4/framework/system/CodeIgniter.php", "line": 988, "trace": [ { "file": "/home/faker/CodeIgniter/c4/vendor/codeigniter4/framework/system/CodeIgniter.php", "line": 988, "function": "forPageNotFound", "class": "CodeIgniter\\Exceptions\\PageNotFoundException", "type": "::" }, { "file": "/home/faker/CodeIgniter/c4/vendor/codeigniter4/framework/system/CodeIgniter.php", "line": 370, "function": "display404errors", "class": "CodeIgniter\\CodeIgniter", "type": "->" }, { "file": "/home/faker/CodeIgniter/c4/public/index.php", "line": 79, "function": "run", "class": "CodeIgniter\\CodeIgniter", "type": "->" }, { "file": "/home/faker/CodeIgniter/c4/vendor/codeigniter4/framework/system/Commands/Server/rewrite.php", "line": 47, "args": [ "/home/faker/CodeIgniter/c4/public/index.php" ], "function": "require_once" } ] }
当前代码
路由文件(Route.php)
<?php use CodeIgniter\Router\RouteCollection; use App\Controllers\TypeBloodController; /** * @var RouteCollection $routes */ $routes->resource('type-blood', ['controller' => TypeBloodController::class]); $routes->get('/', 'Home::index');
控制器文件(TypeBloodController.php)
<?php namespace App\Controllers; use App\Controllers\BaseController; use App\Models\TypeBloodModel; class TypeBloodController extends BaseController { public function index() { $type_blood = new TypeBloodModel(); $datas = $type_blood->findAll(); $this->response->setContentType('application/json'); return $this->response->setJSON($datas); } public function store() { $type_blood = new TypeBloodModel(); $validation = $type_blood->getRuleGroup('blood_store'); $this->response->setContentType('application/json'); return $this->response->setStatusCode(200)->setJSON(['message' => 'Insertion done.']); } public function show($id) { $type_blood = new TypeBloodModel(); $register = $type_blood->find($id); if (!$type_blood) { return $this->response->setStatusCode(404)->setJSON(['message' => "Register not found."]); } $this->response->setContentType('application/json'); return $this->response->setJSON($register); } public function update($id) { $type_blood = new TypeBloodModel(); $register = $type_blood->find($id); if (!$register) { return $this->response->setStatusCode(404)->setJSON(['message' => "Register updated."]); } $validation = $registro->getRuleGroup('blood_update'); $this->response->setContentType('application/json'); return $this->response->setJSON($register); } public function destroy($id) { $type_blood = new TypeBloodModel(); $register = $type_blood->find($id); if (!$register) { return $this->response->setStatusCode(404)->setJSON(['message' => "Register not found"]); } $register->delete($id); $this->response->setContentType('application/json'); return $this->response->setStatusCode(200)->setJSON(['message' => 'Exclusion done.']); } }
问题原因与修复
核心问题:路由控制器参数导致命名空间重复
错误信息中的控制器路径\\App\\Controllers\\App\\Controllers\\TypeBloodController是重复命名空间的结果。因为TypeBloodController::class会返回完整命名空间App\Controllers\TypeBloodController,而CodeIgniter4路由会自动为控制器名称拼接默认命名空间App\Controllers\,两者叠加导致路径错误。
路由修复方案
将路由定义中的controller参数改为字符串形式,二选一即可:
- 仅使用控制器类名(框架自动拼接默认命名空间):
$routes->resource('type-blood', ['controller' => 'TypeBloodController']);
- 使用完整命名空间字符串:
$routes->resource('type-blood', ['controller' => 'App\Controllers\TypeBloodController']);
控制器额外问题修复
除路由外,控制器还有几处逻辑错误需修正:
show()方法:判断条件if (!$type_blood)改为if (!$register),否则永远不会触发404返回update()方法:变量$registro拼写错误改为$type_blood;未找到记录时的提示文案改为"Register not found."destroy()方法:删除操作$register->delete($id)改为$type_blood->delete($id),因为$register是查询结果而非模型实例
修改后的控制器关键片段:
public function show($id) { $type_blood = new TypeBloodModel(); $register = $type_blood->find($id); if (!$register) { return $this->response->setStatusCode(404)->setJSON(['message' => "Register not found."]); } $this->response->setContentType('application/json'); return $this->response->setJSON($register); } public function update($id) { $type_blood = new TypeBloodModel(); $register = $type_blood->find($id); if (!$register) { return $this->response->setStatusCode(404)->setJSON(['message' => "Register not found."]); } $validation = $type_blood->getRuleGroup('blood_update'); $this->response->setContentType('application/json'); return $this->response->setJSON($register); } public function destroy($id) { $type_blood = new TypeBloodModel(); $register = $type_blood->find($id); if (!$register) { return $this->response->setStatusCode(404)->setJSON(['message' => "Register not found"]); } $type_blood->delete($id); $this->response->setContentType('application/json'); return $this->response->setStatusCode(200)->setJSON(['message' => 'Exclusion done.']); }
内容的提问来源于stack exchange,提问作者user22236733
相关产品推荐
相关产品推荐

