a small hack for the Zend_Db_Table_Row class
the Core of any modern web application is the interaction with the database. In the event that the application selected the Zend Framework we will inevitably face using the Zend_Db_Table_Abstract class. This class successfully implements the CRUD functions for work with databases, but, nevertheless, this design has one drawback.
/ > Consider the following structure of the database:
In this DB are two entities – news and comments to news. It is obvious that one news can be left a lot of comments.
Set ourselves the task – to select all news and comments to them and pass information to the view. How to approach it from the point of view of the Zend_Db_Table_Abstract class? Suppose that we have the appropriate model – News and Comments.
Choose all the news is quite simple:
Then, following the logic you need in a loop to bypass all the the news and choose for each news all comments belonging to it. Here the main question arises – where to write the array of objects?
Really want to do this:
But we get an exception stating " " Specified column "comments" is not in the row. The fact that each variable $record is an object of type Zend_Db_Table_Row_Abstract. Trying to assign it to the comments property of the array (actually an object of type Zend_Db_Table_Rowset_Abstract), we call the method __set(). Inspect it:
It is clear that the assignment is possible only if the property is registered in the array $_data. Well, in an array of date it falls through the study of the meta information of the tables involved in the query. It is obvious that in our case the field comments there never will be.
Finally we got to the solution. The worst thing you can do, is to fix problems directly in the code of Zend_Db_Table_Row_Abstract class and throw out a test check in the array $_data. Naturally, we will not do so, we would prefer the PLO. All you need to do is to create a custom Row and Rowset classes.
Here is the code of the new class Row (put it in the file /library/Main/Db/Table/Row.php):
Here is the code of the new class Rowset (file /library/Main/Db/Table/Rowset.php):
That's not all, now make our model to use these classes. The example model News:
Everything is almost ready. The final touch, let's modify the code to add comments to object news:
Now it works!
Article based on information from habrahabr.ru
/ > Consider the following structure of the database:
In this DB are two entities – news and comments to news. It is obvious that one news can be left a lot of comments.
Set ourselves the task – to select all news and comments to them and pass information to the view. How to approach it from the point of view of the Zend_Db_Table_Abstract class? Suppose that we have the appropriate model – News and Comments.
Choose all the news is quite simple:
$News=new News();
$news=$News->fetchAll();
* This source code was highlighted with Source Code Highlighter.
Then, following the logic you need in a loop to bypass all the the news and choose for each news all comments belonging to it. Here the main question arises – where to write the array of objects?
Really want to do this:
foreach($as $record)
{
$comments=$Comments->fetchAll(“news_id=”.$record- > news_id);
$record- > comments=$comments;
}
$this->view->news=$news;
* This source code was highlighted with Source Code Highlighter.
But we get an exception stating " " Specified column "comments" is not in the row. The fact that each variable $record is an object of type Zend_Db_Table_Row_Abstract. Trying to assign it to the comments property of the array (actually an object of type Zend_Db_Table_Rowset_Abstract), we call the method __set(). Inspect it:
public function __set($columnName, $value)
{
$columnName = $this->_transformColumn($columnName);
if (!array_key_exists($columnName, $this->_data)) {
require_once 'Zend/Db/Table/Row/Exception.php';
throw new Zend_Db_Table_Row_Exception("Specified column \"$columnName\" is not in the row");
}
$this->_data[$columnName] = $value;
$this->_modifiedFields[$columnName] = true;
}
* This source code was highlighted with Source Code Highlighter.
It is clear that the assignment is possible only if the property is registered in the array $_data. Well, in an array of date it falls through the study of the meta information of the tables involved in the query. It is obvious that in our case the field comments there never will be.
Finally we got to the solution. The worst thing you can do, is to fix problems directly in the code of Zend_Db_Table_Row_Abstract class and throw out a test check in the array $_data. Naturally, we will not do so, we would prefer the PLO. All you need to do is to create a custom Row and Rowset classes.
Here is the code of the new class Row (put it in the file /library/Main/Db/Table/Row.php):
<?php
class Main_Db_Table_Row extends Zend_Db_Table_Row
{
public function newDataProperty($value)
{
if(!array_key_exists($value,$this->_data))
$this->_data[$value]="";
}
}
* This source code was highlighted with Source Code Highlighter.
Here is the code of the new class Rowset (file /library/Main/Db/Table/Rowset.php):
<?php
class Main_Db_Table_Rowset extends Zend_Db_Table_Rowset
{
function init()
$this->_rowClass='Main_Db_Table_Row';
}
}
* This source code was highlighted with Source Code Highlighter.
That's not all, now make our model to use these classes. The example model News:
<?php
class News extends Zend_Db_Table_Abstract
{
protected $_name='news';
protected $_primary='news_id';
function init()
{
$this->by specifying them with the('Main_Db_Table_Row');
$this->setRowsetClass('Main_Db_Table_Rowset');
}
}
* This source code was highlighted with Source Code Highlighter.
Everything is almost ready. The final touch, let's modify the code to add comments to object news:
foreach($as $record)
{
$comments=$Comments->fetchAll(“news_id=”.$record- > news_id);
$record->newDataProperty(‘comments’);
$record- > comments=$comments;
}
$this->view->news=$news;
* This source code was highlighted with Source Code Highlighter.
Now it works!
Комментарии
Отправить комментарий