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服务,所以childWebsiteServicePage
class很重要。我还想在我将来开发的任何网站上重用这个模型(有一些明显的修改),所以我真的需要知道我在这里做错了什么!再次感谢:-)
事实证明,我只是错误地实例化了子对象,通过复制父对象的实例化并愚蠢地忘记将 WebsitePage
更改为 WebsiteServicePage
! 虽然我写题的时候想起来了!拍额头
非常非常感谢那些试图在评论中提供帮助的人;如果不是因为你的明智之言(尤其是@hakre 的),我不会想出这个!
编辑:根据@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服务,所以childWebsiteServicePage
class很重要。我还想在我将来开发的任何网站上重用这个模型(有一些明显的修改),所以我真的需要知道我在这里做错了什么!再次感谢:-)
事实证明,我只是错误地实例化了子对象,通过复制父对象的实例化并愚蠢地忘记将 WebsitePage
更改为 WebsiteServicePage
! 虽然我写题的时候想起来了!拍额头
非常非常感谢那些试图在评论中提供帮助的人;如果不是因为你的明智之言(尤其是@hakre 的),我不会想出这个!