2011-04-25 60 views
2

我想要一个扩展AppController的ThingsController。我个人的控制器将扩展ThingsController。这些功能对每个型号都是重复的,每个型号都有自己的主要冗余控制器。cakephp如何拥有其他控制器扩展的控制器类

A)这是一个好主意吗?

B)我该怎么做?我尝试将它添加到控制器目录,但蛋糕没有找到它。

c)我应该如何在beforeFilter和beforeRender中编码?这包括验证。

回答

10

它会正常工作。控制器只不过是PHP类,只要Cake可以找到它们,你可以让它们继承你喜欢的任何方式。

  1. 创建ThingsController和/其放置在应用程序/控制器things_controller.php
  2. 在派生控制器,添加App::import('Controller', 'Things');类定义的上方。
  3. 正确定义类:class TestController extends ThingsController {}

过滤器将继承像正常。

+0

这些日子如果使用PHP 5.4+,你可以使用** Traits **,它的优点是一个类可以有几个。在PHP中没有多重继承,并且试图将大量共享代码塞进继承树中会变得复杂。参见http://www.php.net/manual/en/language.oop5.traits.php – Annabel 2014-04-12 11:31:05

+1

如上面建议的那样使用App :: import,以及2.0文档中建议的使用App :: uses,都会产生一个对于我来说类没有找到错误。 – 2014-11-13 19:28:38

1

现在你可以使用App::uses('ClassName', 'Folder/Subfolder')

扩展一个类什么也不做你在数据库表中的条款......只要你扩展的模式,你的扩展模型的名字是表名那块蛋糕看起来在数据库中。您无法将常用字段存储在公用表中,并且扩展字段位于扩展类表中。因为无论如何你都需要模型关联,所以CakePHP没有太多的关键点扩展模型和控制器。为了让多个模型处理同一个表格,您可以用$ useTable覆盖模型在Model定义中使用的表格,但我无法想象除了您的项目需要与表格交谈之外,重命名。

所以你的情况,我会说Automobile extends AppModelCar extends AppModelTruck extends AppModel,(正常蛋糕模型)Truck $belongsTo AutomobileCar $belongsTo Automobile。将您的共同属性和方法放在汽车中,就像您要从汽车延伸一样,而不是继承方法,您可以通过模型关联访问它们,如$this->Truck->Automobile->vin中使用对象表示法而不是使用$this->Truck->vin这是您想要执行的操作与继承。

换句话说,通过在cakePHP中扩展模型 - 这是通过模型关联完成的,您不会接近数据库规范化。你从AppModel和AppController继承,以便获得如find(),save()等和诸如beforeFilter()和afterRender()等回调的基本方法等等。当你重写像beforeFilter()这样的回调函数时,扩展课程,你必须调用parent::beforeFilter()里面的方法或东西会破坏。

我想你可以有一个表中的扩展属性的所有字段(表汽车字段年,vin和box_length,trunk_litres),然后从基类扩展模型,并覆盖扩展表模型使用基类表名称(class Car extends Auto {$useTable = auto}),但是这会在表中留下大量空字段,并且不是正确的标准化表结构。这将是一种有说法的方式,尽管如此,VIN在所有扩展类中都是独一无二的领域。不知道在这种情况下,ID的auto_increment是如何工作的。但是随后需要额外的工作才能从与扩展类的类型相匹配的给定类型的公共表记录中提取(table auto has field auto_type,class Truck extends Auto {$autoType = 'truck'}),所以没有收益。

同样没有意见收益。如果您有class AutoController extends AppController { function displayListing()},然后class TruckController extends AutoController,则可以拨打TruckController->display_listing(),但除非您将动作告诉$this->render('Auto/display_listing'),否则您需要在/View/Truck/display_listing.ctp中创建视图的副本,并且如果您执行覆盖,那么View/Auto/display_listing.ctp中的视图将不得不具有许多if声明来渲染特定于卡车或汽车的部分视图,所以再次没有收益。