Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/252.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
告诉PHP类始终运行它';当它被扩展时,它是一个构造函数_Php_Class_Constructor_Extend - Fatal编程技术网

告诉PHP类始终运行它';当它被扩展时,它是一个构造函数

告诉PHP类始终运行它';当它被扩展时,它是一个构造函数,php,class,constructor,extend,Php,Class,Constructor,Extend,据我所知,当一个PHP类被扩展时,它的构造函数不会被调用?因此,在下面的例子中,方法Options\u Page\u Template->on\u enqueue\u scripts()从未真正运行过- class Options_Page_Template{ function __construct(){ /** Enqueue scrips and styles for use in this plugin */ add_action('wp_e

据我所知,当一个PHP类被扩展时,它的构造函数不会被调用?因此,在下面的例子中,方法
Options\u Page\u Template->on\u enqueue\u scripts()
从未真正运行过-

class Options_Page_Template{

    function __construct(){ 

        /** Enqueue scrips and styles for use in this plugin */
        add_action('wp_enqueue_scripts', array(&$this, 'on_enqueue_scripts'));

    }

    function on_enqueue_scripts(){

        { do Whatever here }

    }

}

class Options_Home extends Options_Page_Template{

    function __construct(){ 

        { Add various actions here }

    }


}
有没有办法告诉
Options\u Page\u Template()
在扩展时始终运行它自己的
\u构造函数()
?我知道我可以使用
parent::u construct()
,但这需要将代码添加到扩展类的所有文件中


我还尝试了将构造函数命名为类的老方法,但PHP显然比这更聪明,因为它不起作用。谢谢。

只是不要为扩展类定义构造函数。

没有办法。对于所有代码来说,一个很好的经验法则是始终为覆盖构造函数的每个子类调用parent::u构造;如果没有,请在构造函数中显式注释,并说明原因


一般来说,对于函数和con/析构函数,如果您重写了某些内容;您还负责调用父函数。

您可以做一些令人讨厌的事情,比如将构造函数定义为final,并拥有一个受保护的init方法,扩展类可以覆盖该方法,但老实说,我不建议这样做

这样,如果有人试图在子类中编写构造函数,他们将得到如下结果:

PHP致命错误:无法重写PHP shell代码第5行中的最终方法A::_construct()

你可能需要换一种方式来组织你的课程

class Options_Home extends Options_Page_Template{

    function __construct() { 
       parent::__construct(); // Needs to be first line so the rest of the constructor
                              // can assume the Options_Page_Template has been constructed.
       // Various stuff here for Options_home constructor

    }


}

应该可以工作。

您必须始终使用
父::\u构造()
如果您要在两个类中创建一个\u构造,您确实可以选择将其转过来。您可以让父类构造函数检查子类中是否存在自定义构造函数并运行它

<?php
class Options_Page_Template{
    function __construct(){ 
        if (method_exists($this,'__beforeconstruct'))
          $this->__beforeconstruct();

        echo "construct class<br/>";

        if (method_exists($this,'__afterconstruct'))
          $this->__afterconstruct();

    }

    function on_enqueue_scripts(){
    }
}

class Options_Home extends Options_Page_Template{
    function __beforeconstruct(){ 
       echo "Extended class before<br/>";
    }

    function __afterconstruct(){ 
       echo "Extended class after<br/>";
    }
}

new Options_Home();

?>

简短回答:否。如果子类重载构造函数,它必须调用父类::\u construct(),才能运行父类构造函数。故事结束。遗憾的是,这不是一个选项,因为我需要在页面加载时钩住各种操作。然后您需要调用
parent::\uu construct()在每个构造函数中,我都这么想,但这有点遗憾。也许这是未来版本的东西。谢谢你的答复。不。这将违反面向对象编程背后的一个基本思想:每个类都有责任关心其内部的正确性。如果我可以强制使用基构造函数,我将从继承的类中解脱出来。我认为这个类不想调用父类的构造函数,然后它必须自己处理事情。@ChristophGrimmer Dietrich:这里的空间有限,但我通常100%同意方法,但我认为构造函数有点奇怪。首先,PHP在子类化时不强制构造函数签名。第二:如果父类来自不同的包,但构造函数主体发生了变化。。这不是API更改。除非有很好的理由不这样做,否则尝试总是将父构造函数作为一种习惯,这有助于提高健壮性。@Evert这里有一点误解。我回应了大卫,并全心全意地支持你的回答。当然,你应该总是调用被重写的方法,不管是否调用构造函数,除非有很好的理由不这样做。@ChristophGrimmer Dietrich:啊,我明白了:)谢谢你的评论。谢谢@Jason,我也有同样的想法(看看组织)。在构造函数上加上“final”的确是一件令人讨厌的事情。但是,我在大型组件中多次看到了您的建议,这些组件需要很多子类来实现自定义构造逻辑。如果遇到这样的问题,通常会认为这是你的对象设计中的一个问题。否则,实现一个在构造函数中被调用的空白且受保护的“init()”方法没有什么错。谢谢@Niko。我认为你的
init()
建议本质上就是@HugoDelsing在他的回答中所建议的,这也是我可能会采用的方法。实际上,这是一种非常巧妙的方法。测试和工作,应该达到我想要的。非常感谢。
Extended class before
construct class
Extended class after