PHP child class' 函数覆盖未被调用

PHP child class' function override is not being called

编辑:根据@hakre 的要求,这是parent class 的简化版本。请参阅下面的完整原始问题。

class WebsitePage {
    protected $name;
    protected $slug;
    protected $heading;
    protected $intro;
    protected $content;

    // constructor and other unrelated functions, including name()
    // which just spits out a simple string passed into the constructor,
    // and heading(), which wraps that in a <h1> tag.
    ...

    public function slug() {
        return isset($this->slug) ? $this->slug : strtolower(
            str_replace(array(' ', '/'), '-', $this->name));
    }

    public function content() {
        return isset($this->content) ? $this->
            content : $this->get_template();
    }

    protected function get_template() {
        ob_start();
        include(__DIR__ . '/templates/' . (!empty($this->
            slug()) ? $this->slug() : $this->name) . '.php');

        $content = ob_get_contents();
        ob_end_clean();

        return $this->intro() . $content;
    }
}

原文:与 this question 类似,我无法让 class 继承(特别是函数覆盖)按照每个 PHP 资源指定的方式工作。

Parent class:

class WebsitePage {
    protected $name;
    protected $slug;
    protected $heading;
    protected $intro;
    protected $content;

    public function __construct($name, $slug = null, $heading = null, $intro = null, $content = null) {
        $this->name = $name;
        $this->slug = $slug;
        $this->heading = $heading;
        $this->intro = $intro;
        $this->content = $content;
    }

    public function name() {
        return $this->name;
    }

    public function slug() {
        return isset($this->slug) ? $this->slug : strtolower(
            str_replace(array(' ', '/'), '-', $this->name));
    }

    public function heading() {
        return isset($this->heading) ? $this->
            heading : "<h1>$this->name</h1>";
    }

    public function intro() {
        return '<div class="page-intro">' . (!isset($this->intro) ? $this->
            heading : "$this->heading<p>$this->intro</p>") . '</div>';
    }

    public function content() {
        return isset($this->content) ? $this->
            content : $this->get_template();
    }

    protected function get_template() {
        ob_start();
        include(__DIR__ . '/templates/' . (!empty($this->
            slug()) ? $this->slug() : $this->name) . '.php');

        $content = ob_get_contents();
        ob_end_clean();

        return $this->intro() . $content;
    }
}

Child class:

class WebsiteServicePage extends WebsitePage {
    public function __construct($name, $slug = null, $heading = null, $intro = null, $content = null) {
        parent::__construct($name, $slug, $heading, $intro, $content);
    }

    public function slug() {
        return 'our-services/' . parent::slug();
    }

    public function heading() {
        return isset($this->heading) ? $this->
            heading : "<h2>$this->name</h2>";
    }
}

实例化:

$servicePages = array(
    new WebsiteServicePage('Tree Lopping'),
    new WebsiteServicePage('Land Clearing')
    ...more service page instantiations
);

foreach ($servicePages as $servicePage) {
    echo $servicePage->content();
}

循环的每次迭代都会导致 parent class' content() 被调用,它调用它自己的 get_template(),它调用它自己的 slug(),因此从最后一页 slug 中省略了 /our-services。这意味着 get_template() 找不到正确的模板文件,因为它们存在于 our-services 目录中。

我可以简单地将所有模板放在同一个目录中来解决这个问题,但我觉得我一定是误解了一些关于 PHP class 继承的基本知识。尽管如前所述,我能够找到的每一个 PHP 资源都表明我所做的应该有效!

那么是什么原因呢? MTIA! :-)

P.S。 Whosebug 建议我应该在我的问题中添加更多 non-code 内容,所以对于那些关心的人来说,这是我为经营树 lopping/arborism 业务的客户构建的网站。他们提供各种tree-related服务,所以childWebsiteServicePageclass很重要。我还想在我将来开发的任何网站上重用这个模型(有一些明显的修改),所以我真的需要知道我在这里做错了什么!再次感谢:-)

事实证明,我只是错误地实例化了子对象,通过复制父对象的实例化并愚蠢地忘记将 WebsitePage 更改为 WebsiteServicePage虽然我写题的时候想起来了!拍额头

非常非常感谢那些试图在评论中提供帮助的人;如果不是因为你的明智之言(尤其是@hakre 的),我不会想出这个!