Skip to content
Advertisement

Codeigniter4 how to call parent controller’s constructor from derived class constructor

In Codeignter 4 we can’t use constructor in BaseController. But the method initController() will do it. But how can call this method from derived controller’s constructor?

My question is that BaseController::is_allowed() method will do all basic features that are commonly useful for all derived controller classes. But to work BaseController::is_allowed() , BaseController::__construct() should be execute before this. But as in CI-4, constructor is not allowed in BaseController. It can have BaseController::initController(). But the problem is that this method will execute only after DerivedClass::__construct().

I need to execute BaseController::is_allowed() before executing every derived class methods. So I call BaseController::is_allowed() method in constructor of derived controllers. But derived class constructor executes before the execution of BaseController::initController(). So BaseController::is_allowed() not works.

BaseController.php

<?php

namespace AppControllers;

use CodeIgniterController;
use CodeIgniterHTTPCLIRequest;
use CodeIgniterHTTPIncomingRequest;
use CodeIgniterHTTPRequestInterface;
use CodeIgniterHTTPResponseInterface;
use PsrLogLoggerInterface;


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.
    }
}

And the derived class as

Users.php

<?php

namespace AppControllers;

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();
    }
}

Advertisement

Answer

Basically your Users Controller should use the iniController and not the construct, like so:

<?php

namespace AppControllers;
use CodeIgniterHTTPRequestInterface; 
use CodeIgniterHTTPResponseInterface; 
use PsrLogLoggerInterface;

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

However its a good practice to create your is_allowed function in your BaseController as a protected function, otherwise one might be able to access it via any url like site.com/users/is_allowed

I might even add that if the purpose of the is_allowed function is to check if the user has permission to do an action or even be in that controller your should look into Filters and not this

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement