2011-03-20 104 views
2

我從Zend Framework開始,我對模型和relathionships(一對多,多對多等)有點困惑。Zend模型和數據庫關係

的「Zend框架快速入門」說要建立一個Zend_Db_Table類,一個數據映射,最後 我們的模型類

假設我們有一個這樣的數據庫:

table A (
id integer primary key, 
name varchar(50) 
); 

table B (
id integer primary key, 
a_id integer references A 
); 

,那我就創建:

Application_Model_DbTable_A extends Zend_Db_Table_Abstract, 
Application_Model_AMapper, 
Application_Model_A, 

Application_Model_DbTable_B extends Zend_Db_Table_Abstract, 
Application_Model_BMapper, 
Application_Model_B, 

,如果我的理解,我給的參考信息存儲在 Application_Model_DbTable_A:

protected $_dependentTables = array('B'); 

和Application_Model_DbTable_B:

protected $_referenceMap = array(
    'A' => array(
     'columns' => array('a_id'), 
     'refTableClass' => 'A', 
     'refColums' => array('id') 
    ) 
); 

和我的模型類:

class Application_Model_A 
{ 
    protected $_id; 
    protected $_name; 

    public function __construct(array $options = null) 
    { 
     if(is_array($options)) { 
     $this->setOptions($options); 
     }  
    } 

    public function __set($name, $value) 
    { 
     $method = 'set' . $name; 
     if (('mapper' == $name) || !method_exists($this, $method)) { 
      throw new Exception('Invalid property'); 
     } 
     $this->$method($value); 
    } 

    public function __get($name) 
    { 
     $method = 'get' . $name; 
     if (('mapper' == $name) || !method_exists($this, $method)) { 
      throw new Exception('Invalid property'); 
     } 
     return $this->$method(); 
    } 

    public function setOptions(array $options) 
    { 
     $methods = get_class_methods($this); 
     foreach ($options as $key => $value) { 
      $method = 'set' . ucfirst($key); 
      if (in_array($method, $methods)) { 
       $this->$method($value); 
      } 
     } 
     return $this; 
    } 

    public function setName($name) 
    { 
     $this->_name = (string) $name; 
     return $this; 
    } 

    public function getName() 
    { 
     return $this->_name; 
    } 

    public function setId($id) 
    { 
     $this->_id = (int) $id; 
     return $this; 
    } 

    public function getId() 
    { 
     return $this->_id; 
    } 

class Application_Model_B 
{ 
    protected $_id; 
    protected $_a_id; 

    public function __construct(array $options = null) 
    { 
     if(is_array($options)) { 
     $this->setOptions($options); 
     }  
    } 

    public function __set($name, $value) 
    { 
     $method = 'set' . $name; 
     if (('mapper' == $name) || !method_exists($this, $method)) { 
      throw new Exception('Invalid property'); 
     } 
     $this->$method($value); 
    } 

    public function __get($name) 
    { 
     $method = 'get' . $name; 
     if (('mapper' == $name) || !method_exists($this, $method)) { 
      throw new Exception('Invalid property'); 
     } 
     return $this->$method(); 
    } 

    public function setOptions(array $options) 
    { 
     $methods = get_class_methods($this); 
     foreach ($options as $key => $value) { 
      $method = 'set' . ucfirst($key); 
      if (in_array($method, $methods)) { 
       $this->$method($value); 
      } 
     } 
     return $this; 
    } 

    public function setA_id($a_id) 
    { 
     $this->_a_id = (int) $a_id; 
     return $this; 
    } 

    public function getA_id() 
    { 
     return $this->_a_id; 
    } 

    public function setId($id) 
    { 
     $this->_id = (int) $id; 
     return $this; 
    } 

    public function getId() 
    { 
     return $this->_id; 
    }  

它是正確的?

+2

你試試吧,它的工作原理?如果不是,你會得到什麼錯誤信息? – markus 2011-03-20 00:08:05

+0

我想他正試圖理解zend框架如何處理多對一和多對多的映射以及可能的級聯效應。 – kjy112 2011-03-20 01:28:00

+0

你可以嘗試減少一半的代碼,並提出更具體的問題。寫下你的大聲思考協議。 – markus 2011-03-20 13:39:46

回答

0

那麼讓我們假設你有一個名爲products的db表。你想訪問這個表格並使用這些數據。

首先,你在models/dbtable/文件夾中的文件Product.php需要告訴ZF哪裏尋找數據:

class Default_Model_DbTable_Product extends Zend_Db_Table_Abstract 
{ 
    protected $_name = 'products'; 

} 

所以$_name是db表的名稱。其次,您需要一個存儲所有信息(如產品屬性)的類。假設一個產品只有一個名稱:

class Default_Model_Product{ 

    protected $_name; 

    public function setName($name) { 
     $this->_name = $name; 
     return $this; 
    } 

    public function getName() { 
     return $this->_name; 
    } 

    public function __construct(array $options = null) { 
     if (is_array ($options)) { 
      $this->setOptions ($options); 
     } 
    } 
    //you need the methods below to access an instanz of this class 
    //put it in every model class 
    public function __set($name, $value) { 
     $method = 'set' . $name; 
     if (('mapper' == $name) || ! method_exists ($this, $method)) { 
      throw new Exception ('Invalid product property'); 
     } 
     $this->$method ($value); 
    } 

    public function __get($name) { 
     $method = 'get' . $name; 
     if (('mapper' == $name) || ! method_exists ($this, $method)) { 
      throw new Exception ('Invalid product property'); 
     } 
     return $this->$method(); 
    } 

    public function setOptions(array $options) { 
     $methods = get_class_methods ($this); 
     foreach ($options as $key => $value) { 
      $method = 'set' . ucfirst ($key); 
      if (in_array ($method, $methods)) { 
       $this->$method ($value); 
      } 
     } 
     return $this; 
    } 
} 

最後,您需要一個mapper類,在其中實際訪問數據。您從表中檢索數據並將其存儲爲對象的數組:

class Default_Model_ProductMapper { 

    protected $_dbTable; 

    public function setDbTable($dbTable) { 
     if (is_string ($dbTable)) { 
      $dbTable = new $dbTable(); 
     } 
     if (! $dbTable instanceof Zend_Db_Table_Abstract) { 
      throw new Exception ('Invalid table data gateway provided'); 
     } 
     $this->_dbTable = $dbTable; 
     return $this; 
    } 

    public function getDbTable() { 
     if (null === $this->_dbTable) { 
      $this->setDbTable ('Default_Model_DbTable_Product'); 
     } 
     return $this->_dbTable; 
    } 
    //e.g. fetch all 
    public function fetchAll() { 
     $resultSet = $this->getDbTable()->fetchAll(); 
     $entries = array(); 
     foreach ($resultSet as $row) { 
      $entry = new Default_Model_Product(); 
      $entry->setName ($row->name); 
      $entries [] = $entry; 
     } 
     return $entries; 
    } 
} 

這實在是直線前進;)

+1

您還沒有在此提及過關係或相關模型? – Dunhamzzz 2011-11-22 16:43:55

0

我真的建議你使用其他DB-框架在你的MVC-系統。

Zend對數據庫不太好,它的IMO太複雜/編寫的代碼太多。 還有從而起到非常好的與Zend(VC),如PHPActiveRecord框架...

- >http://www.phpactiverecord.org/projects/main/wiki/Frameworks

+0

關係非常容易,幾乎不需要編碼: http://www.phpactiverecord.org/projects/main/wiki/Associations – riyuk 2012-03-12 15:39:35