没有调用PHP子类的函数覆盖

时间:2018-04-22 07:39:45

标签: php subclassing method-overriding php-7.1

编辑:根据@hakre的要求,这是父类的简化版本。有关完整的原始问题,请参见下文。

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;
    }
}

ORIGINAL:与this question类似,我无法让类继承(特别是函数重写)以每个PHP资源指定的方式工作。

家长班:

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;
    }
}

儿童班:

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();
}

在循环的每次迭代中,调用父类“content()”,调用自己的get_template(),调用自己的slug(),因此省略/our-services从最后一页slug。这意味着get_template()无法找到正确的模板文件,因为它们存在于our-services目录中。

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

那是什么给出的? MTIA! : - )

P.S。 StackOverflow建议我应该在我的问题中添加更多非代码内容,所以对于那些关心的人来说,这是我为一个运行树砍/树木业务的客户建立的网站。它们提供各种与树相关的服务,因此子WebsiteServicePage类非常重要。我还想在将来开发的任何网站上重用这个模型(有一些明显的修改),所以我真的需要知道我在这里做错了什么!再次感谢: - )

1 个答案:

答案 0 :(得分:1)

事实证明,我只是通过复制父对象的实例化并且愚蠢地忘记将WebsitePage更改为WebsiteServicePage而错误地实例化了子对象! 尽管我在写这个问题时设法记住这样做了! 拍打额头

很多,非常感谢那些试图在评论中提供帮助的人;如果不是因为你明智的话(特别是@ hakre的话)我不会想到这个!