CodeIgniter Forums

Full Version: How to extend the Controller core class
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello, I am implementing in CI4 some utilities that I had done using CI3. The first I need es extend the controller core class for add it new functionalities. I read the documentation but always CI returns an error. So , somebody can tell me how do it.?
Showing code you tried and telling the actual error you received is the best way to get a good answer. That said - extending the Controller class is pretty simple - you're just extending a normal PHP class, no special MY_ prefixes needed or anything like that.

1. Make a new BaseController class/file. Make sure it is namespaced so the autoloader can find it.

PHP Code:
<?php namespace App\Controllers;

class 
BaseController extends \CodeIgniter\Controller 
{
    public function 
__construct(...$params)
    {
        
parent::__construct(...$params);
    }


2. Have all of your new controllers extend BaseController instead of CodeIgniter\Controller.

Note: you don't need to have the constructor shown here unless you need additional tasks in the constructor. I just showed it here to remind people about the parameter packing/un-packing available in PHP 7.
1) Create a new folder Base ( ./application/Controllers/Base )

2) Create the BaseController.php ( ./application/Controllers/Base/BaseController.php )

PHP Code:
<?php namespace App\Controllers\Base;

/**
 * Class BaseController
 *
 * @package App\Controllers\Base
 */
class BaseController extends \CodeIgniter\Controller
{

    
/**
     * Class variables - public, private, protected and static.
     * -----------------------------------------------------------------------
     */

    /**
     * @var  array
     */
    
protected $helpers = [];

    
/**
     * __construct ()
     * -----------------------------------------------------------------------
     *
     * Class    Constructor
     *
     * NOTE: Not needed if not setting values or extending a Class.
     *
     */
    
public function __construct(...$params)
    {
        
parent::__construct(...$params);

        
// load helpers - helper(['url', 'form']);
        
helper(['url']);
    }

  // End of BaseController Class.

/**
 * ---------------------------------------------------------------------------
 * Filename: BaseController.php
 * Location: ./application/Controllers/Base/BaseController.php
 * ---------------------------------------------------------------------------
 */ 

3) Create the AdminController.php ( ./application/Controllers/Base/AdminController.php )

PHP Code:
<?php namespace App\Controllers\Base;

/**
 * Class AdminController
 *
 * @package App\Controllers\Base
 */
class AdminController extends BaseController
{

    
/**
     * Class variables - public, private, protected and static.
     * -----------------------------------------------------------------------
     */


    /**
     * __construct ()
     * --------------------------------------------------------------------
     *
     * Class    Constructor
     *
     * NOTE: Not needed if not setting values or extending a Class.
     *
     */
    
public function __construct (...$params)
    {
        
parent::__construct(...$params);
        
    }

  // End of AdminController Class.

/**
 * ---------------------------------------------------------------------------
 * Filename: AdminController.php
 * Location: ./application/Controllers/Base/AdminController.php
 * ---------------------------------------------------------------------------
 */ 

4) Create the PublicController.php ( ./application/Controllers/Base/PublicController.php )

PHP Code:
<?php namespace App\Controllers\Base;

/**
 * Class PublicController
 *
 * @package App\Controllers\Base
 */
class PublicController extends BaseController
{

    
/**
     * Class variables - public, private, protected and static.
     * -----------------------------------------------------------------------
     */


    /**
     * __construct ()
     * -----------------------------------------------------------------------
     *
     * Class    Constructor
     *
     * NOTE: Not needed if not setting values or extending a Class.
     *
     */
    
public function __construct(...$params)
    {
        
parent::__construct(...$params);
        
    }

  // End of PublicController Class.

/**
 * ---------------------------------------------------------------------------
 * Filename: PublicController.php
 * Location: ./application/Controllers/Base/PublicController.php
 * ---------------------------------------------------------------------------
 */ 

5) Extending the other Controllers ( ./application/Controllers/Home.php )

PHP Code:
<?php namespace App\Controllers;

// use App\Controllers\Base\AdminController;
use App\Controllers\Base\PublicController;

// class Home extends AdminController
class Home extends PublicController
{
    
/**
     * Class variables - public, private, protected and static.
     * -----------------------------------------------------------------------
     */


    /**
     * __construct ()
     * --------------------------------------------------------------------
     *
     * Class    Constructor
     *
     * NOTE: Not needed if not setting values or extending a Class.
     *
     */
    
public function __construct (...$params)
    {
        
parent::__construct(...$params);

    }

    public function 
index()
    {
        return 
view('welcome_message');
    }

    
//--------------------------------------------------------------------



That's all there is to it.
Thanks for your replies, It's all clear to me now. I corrected my errors and successfully extended the class controllers.
My thanks also go to Kilishan and InsiteFX. I've been trying to do this when converting my CI 3.x code to Ver. 4.
(07-22-2017, 07:46 PM)kilishan Wrote: [ -> ]Showing code you tried and telling the actual error you received is the best way to get a good answer. That said - extending the Controller class is pretty simple - you're just extending a normal PHP class, no special MY_ prefixes needed or anything like that.

1. Make a new BaseController class/file. Make sure it is namespaced so the autoloader can find it.

PHP Code:
<?php namespace App\Controllers;

class 
BaseController extends \CodeIgniter\Controller 
{
    public function __construct(...$params)
    {
        parent::__construct(...$params);
    }


2. Have all of your new controllers extend BaseController instead of CodeIgniter\Controller.

Note: you don't need to have the constructor shown here unless you need additional tasks in the constructor. I just showed it here to remind people about the parameter packing/un-packing available in PHP 7.

What is the proper way to extend the CI4 BaseController where the child class(es) will require a constructor? Very newbie question, but I'm under the impression that if there is an immediate child constructor, one must include...

   
Code:
parent::__construct(...$params);

...in the child's constructor. The "...$params" is the part I'm unsure about. The BaseController constructor (initController) has three params that are required. It's not obvious to me what to include as the params.
Ignore the $params part. That reply was 2.5 years old and things have changed. CodeIgniter's controller doesn't use the constructor anymore.

To explain that part, though, using the three dots converts all arguments passed to the method into an array, $param. Then, when calling the parent method, it takes that array and converts it back to the original arguments. It's basically a lazy way of including all of the arguments without all of the typing. Smile It is a new feature added in one of the PHP 5.6. My Google-fu is failing and I can't find it in the manual, but I did find the rfc for it.
Thanks for the reply. It seems my question is only slightly related to this thread, but hopefully relevant enough to continue. So what I really would like to see is a simple example of how to properly extend the BaseController of CI4 with a child class that implements a constructor. Doesn't that child class constructor method need to call the initController method of BaseController? The CI4 documentation addresses extending the BaseController, but the child class does not have a __construct() function.

Extending the Controller

Is this a proper example?

Code:
class SomeController extends BaseController
{

    public function __construct()
    {
        parent::initController(\Config\Services::request(), \Config\Services::response(), \Config\Services::logger());

        // other stuff needed in my constructor
    }

}