So, I have a class called 'Home' and it extends the class 'Controller' the controller class requires all models in a constructor. This works fine.
Now I have a second class called 'Login' It also extends the class 'Controller' but, it does not call the constructor, and I am confused why it is not calling the constructor in this class.
I have found a workaround and that is to make a constructor in the Login class with Parent::__construct()
when I do that, everything works fine.
But I am working why it does work in the Home class, and its not working in the Login class.
The home controller: (the one without any problems)
Backtrace when I do not force to call the constructor of the extended class:
0 Core\Controller->__construct() called at [/var/www/html/site.luukwuijster.eu/core/Router.php:26] #1 App->__construct() called at [/var/www/html/site.luukwuijster.eu/public/index.php:5]
Backtrace when I am forcing to call the constructor of the extended class:
0 Core\Controller->__construct() called at [/var/www/html/site.luukwuijster.eu/app/controllers/home.php:12] #1 Home->__construct() called at [/var/www/html/site.luukwuijster.eu/core/Router.php:26] #2 App->__construct() called at [/var/www/html/site.luukwuijster.eu/public/index.php:5]
The Login controller: (the one with the problems)
When I am not forcing to call the constructor of the extended class:
Fatal error: Uncaught Error: Class 'App\User' not found in /var/www/html/site.luukwuijster.eu/app/controllers/login.php:21 Stack trace: #0 /var/www/html/site.luukwuijster.eu/core/Router.php(26): Login->login() #1 /var/www/html/site.luukwuijster.eu/public/index.php(5): App->__construct() #2 {main} thrown in /var/www/html/site.luukwuijster.eu/app/controllers/login.php on line 21
Backtrace when I am forcing to call the constructor of the extended class:
Core\Controller->__construct() called at [/var/www/html/site.luukwuijster.eu/app/controllers/login.php:11] #1 Login->__construct() called at [/var/www/html/site.luukwuijster.eu/core/Router.php:26] #2 App->__construct() called at [/var/www/html/site.luukwuijster.eu/public/index.php:5]
As you can see, it works fine when I force to call the constructor, but When I dont force it, it only works in the Home class. (Home controller)
Home controller:
use App\User;
use Core\Controller;
use Core\DB;
class Home extends Controller
{
public function test()
{
return User::name();
}
}
Login Controller:
use App\User;
use Core\Controller;
use Core\DB;
class Login extends Controller
{
//This is the constructor I was talking about to force the calling of
//the constructor in the extended class.
public function __construct()
{
parent::__construct();
}
public function login()
{
return User::name();
}
}
Extended class (controller)
namespace Core;
class Controller
{
public $database;
function __construct()
{
//I have put this here to see the backtrace.
debug_print_backtrace();
$this->database = new DB();
foreach (glob('../app/models/*.php') as $model){
require_once $model;
}
}
Router.php
I've put this in here because when I do not force the calling of the constructor on the extended class it gets called on rule 26 in here.
($this->controller = new $this->controller;
)
class App
{
protected $controller = 'home';
protected $method = 'index';
protected $parameters = [];
protected $a = 0;
public function __construct()
{
$url = $this->Url();
if(file_exists('../app/controllers/'. $url[0] .'.php')){
$this->controller = $url[0];
unset($url[0]);
} else {
if (isset($url[0]))
die(view('error404'));
}
require_once '../app/controllers/'. $this->controller .'.php';
$this->controller = new $this->controller;
if (isset($url[1])){
if (method_exists($this->controller, $url[1])){
$this->method = $url[1];
unset($url[1]);
}else{
die(view('error404'));
}
}
$this->parameters = $url ? array_values($url) : [''];
echo call_user_func_array([$this->controller, $this->method], $this->parameters);
}
public function Url()
{
if(isset($_GET['url'])){
$url = filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL);
$exploded_url = explode('/', $url);
return $exploded_url;
}
}
}
Why is it working fine in the Home controller, and not in the Login Controller?
And what do I have to do to make it work the same way in the Login Controller?
I hope everything is clear, and if you need more code or info you can ask me in the comments.
According to the manual:
For backwards compatibility with PHP 3 and 4, if PHP cannot find a __construct() function for a given class, it will search for the old-style constructor function, by the name of the class. Effectively, it means that the only case that would have compatibility issues is if the class had a method named __construct() which was used for different semantics.
As you have a login()
method in your Login
class, php will use that as the constructor. Note that function names are case-insensitive.
Also note that this behaviour is deprecated in php 7 but has not yet been removed.
As per the manual states:
Note: Parent constructors are not called implicitly if the child class defines a constructor. In order to run a parent constructor, a call to parent::__construct() within the child constructor is required. If the child does not define a constructor then it may be inherited from the parent class just like a normal class method (if it was not declared as private).
Class Login
has a construct thus the parent construct is not implicitly called. It my must be called explicitly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With