覆盖PHP中的静态方法

NSA*_*ict 5 php static overriding

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

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();
    }
};
Run Code Online (Sandbox Code Playgroud)

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

现在我有另一个类,看起来像这样:

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

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

为什么?我能做什么?

编辑

我正在运行PHP 5.2.17

And*_*ier 8

Ilija,PHP <5.3没有" Late Static Binding ",这就是为什么你可能会遇到FooPage::displayContent没有被调用的原因.如果您正在运行PHP 5.2,那么没有什么可做的(除了一些使用debug_backtrace()的黑客,老实说我不建议这种情况).

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

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>";
    }
}
Run Code Online (Sandbox Code Playgroud)

以后在你的视图中你会写如下:

$page = new FooPage();
$page->display();
Run Code Online (Sandbox Code Playgroud)

有些事情需要考虑:

  • 通常最好不要在生成视图内容时使用print/echo.而是尝试创建字符串并作为最后一步执行print/echo.这使得以后编写测试更容易.

例:

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();
Run Code Online (Sandbox Code Playgroud)
  • 如果您需要做的是为你的应用程序的增长,你可以通过页眉和页脚的页面构造函数的参数.只要它们是理解display()消息(即多态)的对象就应该没问题.

HTH