我注意到在某些情况下,当你编写一个扩展现有类的类时,你需要在config.yml文件中声明类扩展。
例如,我最近编写了此代码以删除" help" CMS后端的按钮。
mysite的/代码/ Tweak.php
class Tweak extends LeftAndMainExtension
{
public function init()
{
parent::init();
/* Remove help link */
CMSMenu::remove_menu_item('Help');
}
}
mysite的/代码/ Config.yml
LeftAndMain:
extensions:
- Tweak
问题1:为什么需要在config.yml中声明一些类扩展?为什么这个额外的步骤不是其他类扩展所必需的(例如扩展DataObject或Page_Controller)?
问题2:有关上述代码的具体问题,为什么我在配置文件中将 Tweaks 声明为 LeftAndMain 的扩展名,但是php文件我实际上是在扩展 LeftAndMainExtension 吗?
答案 0 :(得分:8)
你实际上是在谈论两种基本的OO模式。
这几乎是许多语言的标准方法,包括PHP和Java,自定义类从另一个类继承一些逻辑,并能够声明自己的ala:
class MyObject extends DataObject {
}
在这种情况下,SilverStripe没有特定的内容,在这种情况下是原生的(PHP)。
当您继承Extension
或其任何一个子类时,例如DataExtension
,SiteTreeExtension
或LeftAndMainExtension
根据您的示例,您可以进行装饰"一个现有的类和当前的库或框架的"装饰器"的实现。图案。
在SilverStripe中,这两种方法之间的一个很大区别是,对于子类化,新类将在数据库中创建一个新表(在其中声明$db
静态)。使用装饰器(在YML中声明的一个Extension
子类或通过类本身中的$extension
静态),不会创建新表,您只需能够"粘贴& #34;现有对象及其表的新字段和逻辑。
后一种方法实用的一个常见例子是Member
类。对其进行子类化,无法帮助您修改/自定义SilverStripe的会员和权限系统,装饰。
请参阅SilverStripe此功能的专用页面:https://docs.silverstripe.org/en/3.3/developer_guides/extending/extensions/
答案 1 :(得分:7)
问题1 :为什么需要在config.yml中声明某些类扩展?为什么这个额外的步骤不是其他类扩展所必需的(例如扩展DataObject或Page_Controller)?
PHP和SilverStripe术语之间存在重要区别。
在SilverStripe中,扩展是一个在SilverStripe中实现的框架功能,它允许您修改对象的行为,而无需访问除公共内容之外的任何内容。在这方面它与Ruby类似。
在PHP中,您使用extends
关键字来定义现有类的子类。
在您的示例中,您使用的是LeftAndMainExtension
,这是一个SilverStripe"扩展" - 这使您可以在SilverStripe的管理区域中修改CMS菜单的行为,而不会字面上扩展(以PHP术语)LeftAndMain
类。 / p>
问题2 :有关上述代码的具体问题,为什么我在配置文件中声明 Tweaks 作为 LeftAndMain 的扩展名,但是php文件我实际上是在扩展 LeftAndMainExtension 吗?
如上所述,这就是SilverStripe的扩展系统的工作原理。它基本上遵循以下过程:
extends
(PHP关键字)Extension
的类(使用LeftAndMainExtension
,它扩展了Extension
)。对于DataObjects,请改用DataExtension
。LeftAndMain
命名是故意的,因此您可以轻松/直观地将对象及其相关扩展组合在一起:
约定是扩展类名称以Extension结尾。这不是一个要求,但要更清楚
- SilverStripe开发人员文档
注意我故意将Extension扩展为表示它是SilverStripe扩展类,而不是类(class Foo extends Bar
)的PHP扩展。
有关框架如何执行此过程的示例,它基本上是这样的:
Object::add_extension()
应用的扩展程序)扩展$this->owner
设置为当前对象,以便扩展程序可以从中访问公共方法和属性