Good morning all

I'm having a problem with injecting a class into the constructor of another class. I am creating an MVC framework, for learning purposes.

In bootstrap.php, it loads the various classes needed, and also instantiates a few classes

Code snippet for bootstrap.php below.

<?php

/**
* file: /system/core/Bootstrap.php
* System initialization begins here
* Retrieve all essential files, and 
* instantiate classes
*/

// Start the autoloader
require_once(__DIR__.'/../core/Autoload.php');

// Load files from /system/config
$autoload->config( array('config', 'paths') );

// Load files from /system/core
$autoload->core( array('router', 'template', 'loader', 'database', 'KW_Controller') );

// Load helper files from /system/helpers
$autoload->helper( array('formatter', 'date', 'pagination') );

// We have all the files we need
// Now we can initialze the classes

$config = new Config;
`$route = new Router;`
$_db = new Database;
$load = new Loader;

`$_c = new KW_Controller($route);`

$template = new Template($route, $config, $load);

$template->header($route, $config, $load);

$_c->dispatch($load, $route);

$template->footer();

Now, my problem arises from this line of code above, which is in bold: $_c = new KW_Controller($route);

When I try to inject the $route instance into $_c __constructor as shown above; I get the following exception:
*Catchable fatal error: Argument 1 passed to KW_Controller::__construct() must be an instance of Router, none given, called in /var/www/html/kw/system/core/KW_Controller.php on line 32 and defined in /var/www/html/kw/system/core/KW_Controller.php on line 12*

Here is the code snippet for the controller class ( $_c ):

<?php

class KW_Controller {

    private $controller;
    private $controller_class;
    private $controller_filename;
    private static $action;
    private $param;
    private $route;

    public function __construct(Router $route)
    {
        $this->route = $route;
        $this->controller = $route->controller;
        $this->controller_class = str_replace('Controller', '', $this->controller);
        $this->controller_filename = ucwords($this->controller).'.php';
        $this->action = $route->action;
        $this->param = $route->param;
        $action = strtolower($route->action);
    }

    public function dispatch(Loader $load)
    {
        if( is_readable(CONTROLLERS_DIR.$this->controller_filename) )
        {
            require_once CONTROLLERS_DIR.$this->controller_filename;

            if( class_exists($this->controller_class) )
            {
                 // File found and class exists, so instantiate controller class

                 ###################################################################
                 #
                 # Below line is what triggers the exception that I described above
                 # What this does is look at the URI, find the controller being
                 # requested, and instantiate that class
                 #
                 ###################################################################
                 $__instantiate_class = new $this->controller_class;

                 // So now we need to check the requested action
                 $action = strtolower($this->action);
                 if( $action == '' || $action == ' ' || empty($action) )
                 $action = 'index';

                 if( method_exists($__instantiate_class, $action) )
                    // Class method exists
                    return $__instantiate_class->$action();
                 else
                    // Valid controller, but invalid action
                    echo 'Invalid action requested: '.$action;
            }
            else
                // Controller file exists, but class name
                // is not formatted / spelled properly
                echo $__instantiate_class. ' Controller is invalid';
        } 
        else
            // Controller file does not exist, or
            // does not have read permissions (644)
            $load->view('errors/controller');
        }
}

Now, instead of trying to use dependency injection by injecting the Router class as shown above, if I simply create a new Router class inside the __constructor() (example: $this->route = new Router;), then everything works fine; no errors.

What am I doing incorrectly....more specifically, why do I get an error when I instantiate a new controller class when injecting the Router class?

Thank you for any thoughts or feedback!

Okay, so I just deleted the __constructor() in the KW_Controller class, and instead, passed the dependencies directly into the dispatch method....see new code below:

<?php

class KW_Controller {

    private $controller;
    private $controller_class;
    private $controller_filename;
    private static $action;
    private $param;
    private $route;


    public function dispatch(Loader $load, Router $route)
    {

        $this->controller = $route->controller;
        $this->controller_class = str_replace('Controller', '', $this->controller);
        $this->controller_filename = ucwords($this->controller).'.php';
        $this->action = $route->action;
        $this->param = $route->param1;
        $action = strtolower($route->action);

        if( is_readable(CONTROLLERS_DIR.$this->controller_filename) )
        {
            require_once CONTROLLERS_DIR.$this->controller_filename;

            if( class_exists($this->controller_class) )
            {
                 // File found and class exists, so instantiate controller class
                 $__instantiate_class = new $route->controller_class;

                 // So now we need to check the requested action
                 $action = strtolower($route->action);
                 if( $action == '' || $action == ' ' || empty($action) )
                 $action = 'index';

                 if( method_exists($__instantiate_class, $action) )
                    // Class method exists
                    return $__instantiate_class->$action();
                 else
                    // Valid controller, but invalid action
                    // echo 'Invalid action requested: '.$action;
                    $load->view('errors/action');
            }
            else
                // Controller file exists, but class name
                // is not formatted / spelled properly
                echo $__instantiate_class. ' Controller is invalid';
        } 
        else
            // Controller file does not exist, or
            // does not have read permissions (644)
            $load->view('errors/controller');
        }
}

Everything works beautifully now. For some reason, passing it via the constructor caused my problems; just not sure why

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.