2011-04-25 54 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聲明來渲染特定於卡車或汽車的部分視圖,所以再次沒有收益。