PHP - 类不调用扩展类的构造函数,而它在其他类

时间:2017-01-12 14:28:30

标签: php

我的问题:

所以,我有一个名为'Home'的类,它扩展了类'Controller',控制器类需要构造函数中的所有模型。这很好。

现在我有一个名为'Login'的第二个类它还扩展了'Controller'类,但它没有调用构造函数,我很困惑为什么它不调用这个类中的构造函数。

我找到了一个解决方法,就是在使用Parent::__construct()的Login类中创建构造函数时,一切正常。

但是我正在工作,为什么它在Home类中工作,而不是在Login类中工作。

一些信息:

家庭控制器:(没有任何问题的那个)

当我不强制调用扩展类的构造函数时回溯:

  

0 Core \ Controller-> __ construct()在[/var/www/html/site.luukwuijster.eu/core/Router.php:26]调用#1 App-> __ construct()调用[/无功/网络/ HTML / site.luukwuijster.eu /公共/ index.php的:5]

当我强制调用扩展类的构造函数时回溯:

  

0 Core \ Controller-> __ construct()调用于[/var/www/html/site.luukwuijster.eu/app/controllers/home.php:12]#1 Home-> __ construct()调用于[/var/www/html/site.luukwuijster.eu/core/Router.php:26]#2 App-> __ construct()在[/var/www/html/site.luukwuijster.eu/public/index上调用.php:5]

登录控制器:(有问题的那个)

当我不强制调用扩展类的构造函数时:

  

致命错误:未捕获错误:在/var/www/html/site.luukwuijster.eu/app/controllers/login.php:21中找不到类'App \ User'堆栈跟踪:#0 / var / www / html / site.luukwuijster.eu / core / Router.php(26):登录 - >登录()#1 /var/www/html/site.luukwuijster.eu/public/index.php(5):App- > __ construct()#2 {main}在第21行的/var/www/html/site.luukwuijster.eu/app/controllers/login.php中引发

当我强制调用扩展类的构造函数时回溯:

  

在[/var/www/html/site.luukwuijster.eu/app/controllers/login.php:11]调用的Core \ Controller-> __ construct()#1 Login-> __ construct()在[ /var/www/html/site.luukwuijster.eu/core/Router.php:26]#2 App-> __ construct()在[/var/www/html/site.luukwuijster.eu/public/index上调用。 php:5]

正如你所看到的,当我强制调用构造函数时,它工作正常,但是当我不强制它时,它只适用于Home类。 (家庭控制器)

代码:

家庭控制器:

use App\User;
use Core\Controller;
use Core\DB;

class Home extends Controller
{
    public function test()
    {
        return User::name();
    }
}

登录控制器:

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

}

扩展类(控制器)

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 我把它放在这里是因为当我不强制在扩展类上调用构造函数时,它会在这里的规则26中调用。 ($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;
        }
    }
}

我的问题:

为什么它在Home控制器中工作正常,而不是在Login Controller中工作?

我需要做些什么才能让它在登录控制器中以相同的方式工作?

我希望一切都清楚,如果您需要更多代码或信息,可以在评论中问我。

3 个答案:

答案 0 :(得分:10)

根据手册:

  

为了向后兼容PHP 3和4,如果PHP找不到   __construct()函数对于给定的类,它将通过类的名称搜索旧式构造函数。有效,   这意味着唯一会出现兼容性问题的案例是if   该类有一个名为__construct()的方法,用于   不同的语义。

由于您的login()类中有Login方法,因此php会将其用作构造函数。请注意,函数名称不区分大小写。

另请注意,此行为在php 7中已弃用,但尚未删除。

答案 1 :(得分:1)

根据手册说明:

  

注意:如果子类,则不会隐式调用父构造函数   定义构造函数。为了运行父构造函数,调用   子构造函数中的parent :: __ construct()是必需的。如果   child没有定义构造函数,那么它可能会继承自   父类就像普通的类方法(如果它没有声明   作为私人)。

Login有一个构造,因此不会隐式调用父构造。我必须明确地打电话。

答案 2 :(得分:0)

总而言之,页面上的内容是什么,我正在收集,我已经正确了:

登录类具有名为dotnet ConsoleApp1.dll 的方法,但是Class Home没有名为login()的方法。

在旧版本的PHP中,如果找不到名为home()的构造方法,则:

首先:它将检查与类同名的方法,并使用该方法。

下一步:如果找不到与该类同名的方法-它使用扩展类的构造方法。

谢谢!

相关问题