首页 文章

PHP - 类不调用扩展类的构造函数,而它在其他类中工作正常

提问于
浏览
5

我的问题:

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

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

我找到了一个解决方法,那就是使用 Parent::__construct() 在Login类中构建一个构造函数,当我这样做时,一切正常 .

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

一些信息:

The home controller: (没有任何问题的那个)

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

0 Core \ Controller - > __ construct()在[/var/www/html/site.luukwuijster.eu/core/Router.php:26]调用#1 App - > __ construct()调用[/ var / www / 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]中调用

The Login controller: (有问题的那个)

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

致命错误:未捕获错误:在/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( )第21行/var/www/html/site.luukwuijster.eu/app/controllers/login.php中的#2

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

核心\控制器 - > __ construct()调用[/var/www/html/site.luukwuijster.eu/app/controllers/login.php:11]#1登录 - > __ 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类 . (家庭控制器)

代码:

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 (控制器)

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中?

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

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

2 回答

  • 10

    根据手册:

    为了向后兼容PHP 3和4,如果PHP找不到给定类的__construct()函数,它将按类的名称搜索旧式构造函数 . 实际上,这意味着唯一具有兼容性问题的情况是该类是否有一个名为__construct()的方法,该方法用于不同的语义 .

    由于 Login 类中有 login() 方法,php将使用它作为构造函数 . 请注意,函数名称不区分大小写 .

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

  • 1

    根据手册说明:

    注意:如果子类定义构造函数,则不会隐式调用父构造函数 . 为了运行父构造函数,需要在子构造函数中调用parent :: __ construct() . 如果子节点没有定义构造函数,那么它可以像普通类方法一样从父类继承(如果它没有被声明为私有) .

    Login 具有构造,因此不会隐式调用父构造 . 我必须明确地调用它 .

相关问题