【发布时间】:2018-04-22 07:39:45
【问题描述】:
编辑:根据@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;
}
}
原文:类似于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(),因此在最后一页 slug 中省略 /our-services。这意味着get_template() 找不到正确的模板文件,因为它们存在于our-services 目录中。
我可以简单地将所有模板放在同一个目录中来解决这个问题,但我觉得我一定误解了关于 PHP 类继承的一些基本知识。尽管如前所述,我能够找到的每一个 PHP 资源都表明我所做的应该可以工作!
那是什么?大都会! :-)
附: StackOverflow 建议我应该在我的问题中添加更多非代码内容,所以对于那些关心的人来说,这是一个我正在为一个经营树木修剪/树艺业务的客户构建的网站。他们提供各种与树相关的服务,因此子WebsiteServicePage 类非常重要。我还想在我将来开发的任何网站上重用这个模型(有一些明显的修改),所以我真的需要知道我在这里做错了什么!再次感谢:-)
【问题讨论】:
-
$servicePages实例化是怎么回事?这是错误的语法。 -
你能把这个例子简化到最低限度来演示它并询问它吗?对于您所询问的内容,看起来有很多代码,因此不容易阅读并且很难提供帮助。
-
嗯,数组元素由
,分隔,而不是;。这在语法上是错误的。 -
在您的 WebsiteServicePage get_template 方法中 - 您没有返回值 - 应该是
return parent::get_template(); -
您能否创建一个包含最少代码的单代码块示例脚本来演示该问题并将其作为 3v4l.org 的链接提供?正如我看到你所做的编辑 b/c 我会要求的那样,演示问题正在运行的简化(尽可能少)代码示例就是我所要求的(如果我可以向你提出任何要求的话)。
标签: php subclassing overriding php-7.1