覆盖 PHP 中的静态方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13174343/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 04:54:44  来源:igfitidea点击:

Overriding static methods in PHP

phpstaticoverriding

提问by IluTov

I have an abstract page class looking like this:

我有一个看起来像这样的抽象页面类:

abstract class Page {
    public static function display() {
        self::displayHeader();
        self::displayContent();
        self::displayFooter();
    }

    public static function displayContent() {
        print "<p>some content</p>";
    }

    public static function displayHeader() {
        include_once(kContent . "HeaderContent.class.php");
        HeaderContent::display();
    }

    public static function displayFooter() {
        include_once(kContent . "FooterContent.class.php");
        FooterContent::display();
    }
};

I would like to subclass from this, and only override the displayContent method, so the header and footer is being displayed automatically, but still having the option to override the display method, for example for .js files.

我想从这个子类化,并且只覆盖 displayContent 方法,所以页眉和页脚会自动显示,但仍然可以选择覆盖显示方法,例如 .js 文件。

Now I have another class, looking like this:

现在我有另一堂课,看起来像这样:

class FooPage extends Page {
    public static function displayContent() {
        print "<p>Foo page</p>";    
};

Now, instead of calling the FooPage's displayContentmethod, it just calls the one from the superclass.

现在,它不再调用 FooPage 的displayContent方法,而是调用超类中的方法。

Why? What can I do?

为什么?我能做什么?

EDIT

编辑

I'm running PHP 5.2.17

我正在运行 PHP 5.2.17

回答by Andrés Fortier

Ilija, PHP < 5.3 doesn't have "Late Static Binding" and that's why you may be experiencing the FooPage::displayContentnot being called. If you are running PHP 5.2 then there is nothing much to do (except for some hacks using debug_backtrace(), which honestly I wouldn't recommend for this situation).

Ilija,PHP < 5.3 没有“后期静态绑定”,这就是为什么您可能会遇到FooPage::displayContent未被调用的情况。如果您运行的是 PHP 5.2,那么没有什么可做的(除了一些使用 debug_backtrace() 的黑客,老实说,我不建议在这种情况下使用)。

Now, what it really calls my attention is that your methods are all static; is there a reason for this? Why aren't they instance methods? I would expect something like:

现在,真正引起我注意的是你的方法都是静态的;是否有一个原因?为什么它们不是实例方法?我希望是这样的:

include_once(kContent . "HeaderContent.class.php");
include_once(kContent . "HeaderContent.class.php");

abstract class Page 
{
    protected $header;
    protected $footer;

    public function __construct()
    {
        $this->header = new HeaderContent();
        $this->footer = new FooterContent();
    }

    public function display() 
    {
        $this->displayHeader();
        $this->displayContent();
        $this->displayFooter();
    }

    public function displayContent() 
    {
        print "<p>some content</p>";
    }

    public function displayHeader() 
    {
        $this->header->display();
    }

    public function displayFooter() 
    {
        $this->footer->display();
    }
};

class FooPage extends Page 
{
    public function displayContent() 
    {
        print "<p>Foo page</p>";
    }
}

and later in your view you would write something like:

后来在你看来,你会写一些类似的东西:

$page = new FooPage();
$page->display();

Some things to take into account:

需要考虑的一些事项:

  • It is generally better not to use print/echo when generating a view content. Instead try to create the string and do the print/echo as a last step. This makes it easier to later write tests.
  • 在生成视图内容时,通常最好不要使用 print/echo。而是尝试创建字符串并将打印/回显作为最后一步。这使得以后编写测试更容易。

Example:

例子:

public function display() 
{
    return 
           $this->displayHeader() . 
           $this->displayContent() . 
           $this->displayFooter();
}

public function displayContent() 
{
    return "<p>some content</p>";
}

public function displayHeader() 
{
    return $this->header->display();
}
....
$page = new FooPage();
echo $page->display();
  • If you need to do it as your application grows, you can pass the header and footer as Page constructor parameters. As long as they are objects that understand the display() message (i.e. polymorphic) things should be ok.
  • 如果您需要随着应用程序的增长而这样做,您可以将页眉和页脚作为 Page 构造函数参数传递。只要它们是理解 display() 消息(即多态)的对象,事情就应该没问题。

HTH

HTH