最上面的 init() 方法是在 Controller 类中定义的。
然后 ContentController 扩展了 Controller,它覆盖了 Controller 类的 init() 方法,但它也在第一行调用了 parent::init()。然后通常像这样定义所有页面控制器类(对于任何新页面类型),在下面的示例中为默认 Page_Controller 类:
class Page_Controller extends ContentController {
public function init() {
parent::init();
// do your own stuff here
}
}
所以这是传统的基于 PHP 的类扩展机制,但 Silverstripe 还允许您使用 Extensions 和 Data Extensions,这基本上是对现有控制器、数据对象的功能进行扩展。我不会对此进行详细介绍...您可以在此处找到有关此的更多信息:https://docs.silverstripe.org/en/4/developer_guides/extending/extensions/
我的控制器类中通常有这样的东西:
class Page_Controller extends ContentController {
public function init() {
parent::init();
// do your own stuff here
$this->extend('updateInit');
}
}
注意上面的$this->extend('updateInit'); 行。
我可以在 YAML 配置文件中为 Page_Controller 类定义另一个扩展,然后在该类中定义 updateInit() 方法。示例:
class Page_Controller_Extension extends Extension {
public function updateInit() {
// do some more stuff here
}
}
...在这种情况下,您将在 YAML 配置文件中包含类似的内容:
---
Name: siteextensions
After:
- 'framework/*'
- 'cms/*'
---
Page_Controller:
extensions:
- Page_Controller_Extension
请注意,这并不是传统的扩展类的方式,就像在 PHP 中那样,它更像是为控制器类定义一些装饰器。此外,要引用父对象或被装饰的对象,不能只使用$this,您需要使用$this->owner。下面的例子:
class Page_Controller_Extension extends Extension {
public function updateInit() {
// do some more stuff here
if ($this->owner->IsFeatured) {
// do something here
}
}
}
您通常装饰扩展 Extension 类的控制器,如果您想装饰 DataObjects,您可以扩展 DataExtension 类 - 工作方式与上述相同。