CodeIgniter 4命名空间重复自身:找不到控制器或其方法:\\App\\Controllers\\App\\Controllers\\TypeBloodController::index

jaql4c8m  于 9个月前  发布在  其他
关注(0)|答案(2)|浏览(126)

我无法使用CodeIgniter 4框架创建Restful API。
我使用$routes->resource()来定义方法。但是,我无法获得http://localhost:8080/type-blood和其他地址来返回我想要的。
我正确地配置了项目中的数据库,并选择查看数据。
《 Postman 》给我的回报是:

{
  "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.']);
    }
}

46scxncf

46scxncf1#

说明

如果提供的控制器没有前导反斜杠(\),则默认名称空间将被前置。
默认命名空间
当路由器匹配一个控制器时,路由器会在路由器指定的控制器前面添加默认的命名空间值。默认情况下,该值为App\Controllers

摘自CodeIgniter4/app/Config/Routing.php

class Routing extends BaseRouting
{
    // ...
    public string $defaultNamespace = 'App\Controllers';
    // ...
}

字符串
如果设置值为空字符串(“),它会让每个路由指定完全命名空间的控制器:

解决方案

app/Config/Routes.php
1.将默认命名空间设置为空字符串(“)。例如:$routes->setDefaultNamespace('');

  • 将所有基于字符串的控制器语法转换为数组可调用语法。例如:
    • 而不是:* $routes->get('/', 'Home::index');
    • 用途:铝 * $routes->get('/', [Home::class, 'index']);
  • 数组可调用语法(Since v4.2.0.)还允许在使用IDE或代码编辑器时快速导航到方法或控制器。

示例

<?php

use CodeIgniter\Router\RouteCollection;
use App\Controllers\TypeBloodController;
use App\Controllers\Home;

/**
 * @var RouteCollection $routes
 */
$routes->setDefaultNamespace('');

$routes->get('/', [Home::class, 'index']);

$routes->resource('type-blood', ['controller' => TypeBloodController::class]);

4dc9hkyq

4dc9hkyq2#

不幸的是,你不能使用限定名来指定 * 控制器 * 选项。根据文档,这是可能的,但这似乎是一个小错误,因为在这种情况下,它重复了命名空间。
你总是可以用spark命令检查你的路由。检查处理程序列。

php spark routes

字符串
在我的例子中,处理程序是:\App\Controllers\App\Controllers\Home::index,但它应该是:\App\Controllers\Home::index
你可以简单地修复它:

$routes->resource('type-blood', ['controller' => 'TypeBloodController']);


注意事项:如果你的资源和控制器名称相同,你可以省略 controller 选项。所以你可以在技术上将控制器的名称改为 TypeBlood,文件名改为 TypeBlood.php。然后简单地删除 controller 选项。
注意:如果您的控制器不在App\Controllers命名空间中,您可以使用 namespace 选项指定。例如:

$routes->resource('type-blood', ['controller' => 'TypeBloodController', 'namespace' => 'NotApp\Controllers']);


我创建了一个bug issue report,所以可能会在以后的版本中得到修复。

更新:文档将在以后的版本中得到改进。您可以使用以下(完全限定名称),而无需更改 default namespace 配置:

$routes->resource('test1', ['namespace' => '\\', 'controller' => Home::class]);
$routes->resource('test2', ['controller' => '\\' . Home::class]);
$routes->resource('test3', ['controller' => 'Home']);


来源:https://github.com/codeigniter4/CodeIgniter4/issues/8248

相关问题