【问题标题】:Codeigniter4 how to call parent controller's constructor from derived class constructorCodeigniter4如何从派生类构造函数调用父控制器的构造函数
【发布时间】:2021-10-20 17:49:59
【问题描述】:

在 Codeignter 4 中,我们不能在 BaseController 中使用构造函数。但是方法 initController() 会做到这一点。但是如何从派生控制器的构造函数中调用这个方法呢?

我的问题是BaseController::is_allowed() 方法将完成所有对所有派生控制器类通常有用的基本功能。但是要工作 BaseController::is_allowed()BaseController::__construct() 应该在此之前执行。但与 CI-4 中一样,BaseController 中不允许使用构造函数。它可以有BaseController::initController()。但是问题是这个方法只有在DerivedClass::__construct()之后才会执行。

我需要在执行每个派生类方法之前执行BaseController::is_allowed()。所以我在派生控制器的构造函数中调用BaseController::is_allowed() 方法。但是派生类构造函数在BaseController::initController() 执行之前执行。所以BaseController::is_allowed() 不起作用。

BaseController.php

<?php

namespace App\Controllers;

use CodeIgniter\Controller;
use CodeIgniter\HTTP\CLIRequest;
use CodeIgniter\HTTP\IncomingRequest;
use CodeIgniter\HTTP\RequestInterface;
use CodeIgniter\HTTP\ResponseInterface;
use Psr\Log\LoggerInterface;


class BaseController extends Controller
{
    public $request;

    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        
        // Doing all basic setups here that are needed to all other methods in this class.

        // This method will be called only after derivedClass::__construct().
        // But CI-4 not allows to use __construct() method in BaseController class.
        // This causes my problem.
    }

    function is_allowed()
    {
        // Provides all basic features for all derived controller classes.
        // But to work code in this method, initController() method should execute first.
    }
}

而派生类为

Users.php

<?php

namespace App\Controllers;

class Users extends BaseController
{
    public function __construct()
    {
        // BaseController::is_allowed() will provide all basic features for this controller.
        // To work this method, BaseController::initController() should execute.
        // But this will execute only after this ( __construct()) constuctor.
        // In Codeignier-3, BaseController::__construct() was possible.
        // It will execute before derived class constructor.
        $this->is_allowed();
    }
}

【问题讨论】:

  • 您是否尝试将RequestInterface $request, ResponseInterface $response, LoggerInterface $logger 添加到构造参数中?
  • 不,我需要得到这个东西。我如何获得这些变量,因为它在父控制器中可用,但在其构造函数中不可用。派生类::__construct()方法会在执行parent::initController()之前执行
  • codeigniter4.github.io/userguide/incoming/… 应用程序的主请求实例始终可用作类属性$this-&gt;request。来自官方文档

标签: php codeigniter-4


【解决方案1】:

基本上您的用户控制器应该使用 iniController 而不是构造,如下所示:

<?php

namespace App\Controllers;
use CodeIgniter\HTTP\RequestInterface; 
use CodeIgniter\HTTP\ResponseInterface; 
use Psr\Log\LoggerInterface;

class Users extends BaseController
{
    public function initController(RequestInterface $request, ResponseInterface $response, LoggerInterface $logger)
    {
        parent::initController($request, $response, $logger);
        $this->is_allowed();
    }
}

但是,在 BaseController 中创建 is_allowed 函数作为受保护函数是一种很好的做法,否则可以通过任何 url 访问它,例如 site.com/users/is_allowed

我什至可以补充一点,如果 is_allowed 函数的目的是检查用户是否有权执行某项操作,甚至是否在该控制器中,您应该查看 Filters 而不是这个

【讨论】:

  • 对于登录检查,我使用了Filtersis_allowed 提供派生类的基本功能和一些检查。所以不能在Filter
  • 要使用你的代码,我需要把use CodeIgniter\HTTP\RequestInterface;use CodeIgniter\HTTP\ResponseInterface;use Psr\Log\LoggerInterface;放在namespace下面
  • @ShihabuRahman 将其添加到答案中。谢谢。
【解决方案2】:

在 Codeignter 4 中,我们不能在控制器中使用构造函数。

您不用在 BaseController 类中使用典型的构造函数,您仍然可以在 App/Controller 类中使用构造函数。

您无需手动调用initController,这是在引导过程中为您完成的。从 App\Controllers\Users 构造函数中删除该行。

【讨论】:

  • 我已经用更多解释编辑了我的问题。这是我在 Codeigniter 3 中使用的编码结构。但是在CI-4中,我明白,我应该重写我的编码结构,这只是解决方案。是吗?
猜你喜欢
  • 2019-08-07
  • 2018-07-21
  • 2016-07-19
  • 2013-06-23
  • 2018-07-16
  • 1970-01-01
  • 2015-08-18
  • 2012-11-06
  • 2021-10-05
相关资源
最近更新 更多