By default, methods of the Table class return a Rowset in instances of the concrete
class Zend_Db_Table_Rowset, and Rowsets contain a collection
of instances of the concrete class Zend_Db_Table_Row You can
specify an alternative class to use for either of these, but they must be classes
that extend Zend_Db_Table_Rowset_Abstract and
Zend_Db_Table_Row_Abstract, respectively.
You can specify Row and Rowset classes using the Table constructor's options array, in keys 'rowClass' and 'rowsetClass' respectively. Specify the names of the classes using strings.
Example 291. Example of specifying the Row and Rowset classes
<?php
class My_Row extends Zend_Db_Table_Row_Abstract
{
...
}
class My_Rowset extends Zend_Db_Table_Rowset_Abstract
{
...
}
$table = new Bugs(
array(
'rowClass' => 'My_Row',
'rowsetClass' => 'My_Rowset'
)
);
$where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
// Returns an object of type My_Rowset,
// containing an array of objects of type My_Row.
$rows = $table->fetchAll($where);
You can change the classes by specifying them with the
setRowClass() and setRowsetClass()
methods. This applies to rows and rowsets created subsequently; it does not change
the class of any row or rowset objects you have created previously.
Example 292. Example of changing the Row and Rowset classes
<?php
$table = new Bugs();
$where = $table->getAdapter()->quoteInto('bug_status = ?', 'NEW')
// Returns an object of type Zend_Db_Table_Rowset
// containing an array of objects of type Zend_Db_Table_Row.
$rowsStandard = $table->fetchAll($where);
$table->setRowClass('My_Row');
$table->setRowsetClass('My_Rowset');
// Returns an object of type My_Rowset,
// containing an array of objects of type My_Row.
$rowsCustom = $table->fetchAll($where);
// The $rowsStandard object still exists, and it is unchanged.
For more information on the Row and Rowset classes, see this chapter and this one.
You can override the insert() and
update() methods in your Table class. This gives you the
opportunity to implement custom code that is executed before performing the database
operation. Be sure to call the parent class method when you are done.
Example 293. Custom logic to manage timestamps
<?php
class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
public function insert(array $data)
{
// add a timestamp
if (empty($data['created_on'])) {
$data['created_on'] = time();
}
return parent::insert($data);
}
public function update(array $data, $where)
{
// add a timestamp
if (empty($data['updated_on'])) {
$data['updated_on'] = time();
}
return parent::update($data, $where);
}
}
You can also override the delete() method.
You can implement custom query methods in your Table class, if you have frequent
need to do queries against this table with specific criteria. Most queries can be
written using fetchAll(), but this requires that you
duplicate code to form the query conditions if you need to run the query in several
places in your application. Therefore it can be convenient to implement a method in
the Table class to perform frequently-used queries against this table.
Example 294. Custom method to find bugs by status
<?php
class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
public function findByStatus($status)
{
$where = $this->getAdapter()->quoteInto('bug_status = ?', $status);
return $this->fetchAll($where, 'bug_id');
}
}
Some people prefer that the table class name match a table name in the RDBMS by using a string transformation called inflection.
For example, if your table class name is "BugsProducts", it would
match the physical table in the database called "bugs_products", if
you omit the explicit declaration of the $_name class property.
In this inflection mapping, the class name spelled in "CamelCase" format would be
transformed to lower case, and words are separated with an underscore.
You can specify the database table name independently from the class name by
declaring the table name with the $_name class property in each
of your table classes.
Zend_Db_Table_Abstract performs no inflection to map the
class name to the table name. If you omit the declaration of
$_name in your table class, the class maps to a database table
that matches the spelling of the class name exactly.
It is inappropriate to transform identifiers from the database, because this can
lead to ambiguity or make some identifiers inaccessible. Using the
SQL identifiers exactly as they appear in the database makes
Zend_Db_Table_Abstract both simpler and more flexible.
If you prefer to use inflection, then you must implement the transformation
yourself, by overriding the _setupTableName() method in
your Table classes. One way to do this is to define an abstract class that extends
Zend_Db_Table_Abstract, and then the rest of your tables
extend your new abstract class.
Example 295. Example of an abstract table class that implements inflection
<?php
abstract class MyAbstractTable extends Zend_Db_Table_Abstract
{
protected function _setupTableName()
{
if (!$this->_name) {
$this->_name = myCustomInflector(get_class($this));
}
parent::_setupTableName();
}
}
class BugsProducts extends MyAbstractTable
{
}
You are responsible for writing the functions to perform inflection transformation. Zend Framework does not provide such a function.




