2011-10-01 84 views
0

我目前正在研究我的mvc框架(使用PHP)。我看到CakePHP有能力使用「belongsTo」和「hasMany」特性。我正在嘗試創建自己的功能,並遇到問題。假設我們有預約表(id,where,date,year_id)和年份表(id,year)。我知道這個例子可以在沒有問題的情況下用一張表完成,但這只是一個例子。如何讓模型「hasMany」和「belongsTo」? (像cakePHP一樣)

class appointment_model extends model{ 
    public $_belongs_to= array('table'=>'year','field_connector'=>'year_id'); 
    public $one_value; 
} 

......

class year_model extends model{ 
    public $_has_many= array('table'=>'appointment','field_connector'=>'year_id'); 
    public $many_values; 
} 

....

class model{ 

private function select($query=null){ 
    if(!$query)die("Query cannot be null. Line num: " . __LINE__); 
    $results = $this->_db->mysql_select($query); 
    if(count($results)==1){ 
     $one = $this->initialize($results[0]); 
     $this->_do_for_other_tables($one); 
     return $one; 
    }elseif(count($results)>1){ 
     $returns = array(); 
     foreach($results as $result){ 
      $one = $this->initialize($result); 
      $returns[] = $this->_do_for_other_tables($one);  
     } 
     return $returns; 
    }else{ 
     return null; 
    } 

} 


private function _do_for_other_tables(&$one, $rec=1){ 


    if(property_exists($this, 'many_values')){ 
     if(!empty($one->many_values))return; 
     $many = functions::load_model($this->_has_many["table"]); 
     $res = $many->find_by($this->_has_many["field_connector"], $one->id); 
     $one->many_values = $res; 
    } 
    elseif(property_exists($this, 'one_value')){ 
     if(!empty($one->_belongs_to))return; 
     $only_one = functions::load_model($this->_belongs_to["table"]); 
     $field = $this->_belongs_to['field_connector']; 
     $res = $only_one->find_by('id', $one->$field); 
     $one->one_value = $res; 
    } 

} 

} 

基本上這裏所發生的是,我進入無限循環。任何建議如何解決這個問題?如果我需要更多地解釋它,就說出來。

謝謝:)。

+0

你爲什麼又重新發明了輪子?學說開箱即用! – Francesco

+2

@Francesco:這不是因爲你不想知道它是如何在引擎蓋下工作的,別人也不會。我自己構建了大量的框架來滿足我的需求,因爲他們每個人都不適合我。 Vizualni在這裏可能是同樣的東西... –

回答

1

你問題是你把屬性「hasMany」,「belongsTo」,「hasOne」,「etc」當作簡單的屬性,而不是將它們視爲2way關係。我在許多自己的框架中所做的工作就是由程序員手工初始化這些屬性,但是當類初始化時,您會檢查這些屬性並生成將這兩個屬性鏈接在一起的單個對象。

創建一個類似System_DB_Relationship對象的類,並將相同的副本放入兩個初始化模型中。如果您沒有將模型instanciate作爲工廠設計模式,則可以使用靜態$關係模型來存儲您的關係。我傾向於選擇工廠/活動記錄,所以最好管理這些記錄。現在取決於你的模型基類的邏輯,你可能希望在關係中放置一個標誌來說,「嘿,這種關係已經被使用過了」,所以你不會再次傳入它。

另一種方式是始終以下降的方式工作。也就是說,在找到hasMany時忽略它,只創建一個代理方法來加載子元素,但加載所有belongsTo,以便默認加載父代。請注意,如果你有一大組類,這個方法會變得很危險,所以我在我的框架中實現的通常是一個加載參數,它載入X關係的級別。而當你想要hasMany時,你只需使用__call()來攔截對「$ myobject-> subobjects()」的調用,然後立即加載它們。

有很多方法可以做到這一點,只需花時間手動追蹤代碼,查看沒有意義的東西,嘗試一些東西,最終就能找到一些東西。但是正如弗朗西斯科上面所說的,除非你從事一些不能一次完成的舊項目,否則重新發明輪胎是沒有用的。以你正在做的這項工作爲契機,讓它變得更好,並且知道它是如何在引擎蓋下工作的...

+0

謝謝你的回答。我改變了我的模型類的60%,所以我可以使用MySQL選擇查詢與兩個選定的表。這樣做更容易。你的回答非常有幫助。謝謝。 – Vizualni

+1

您可以請用複選標記標記答案,謝謝。這不是我貪婪,它只是它應該在stackoverflow上工作的方式,並且如果你不標記帖子作爲答案,你會降低你的接受分數...... –