PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

Extending the Row class

Zend_Db_Table_Row is the default concrete class that extends Zend_Db_Table_Row_Abstract. You can define your own concrete class for instances of Row by extending Zend_Db_Table_Row_Abstract. To use your new Row class to store results of Table queries, specify the custom Row class by name either in the $_rowClass protected member of a Table class, or in the array argument of the constructor of a Table object.

Example 314. Specifying a custom Row class

<?php
class MyRow extends Zend_Db_Table_Row_Abstract
{
    
// ...customizations
}

// Specify a custom Row to be used by default
// in all instances of a Table class.
class Products extends Zend_Db_Table_Abstract
{
    protected 
$_name 'products';
    protected 
$_rowClass 'MyRow';
}

// Or specify a custom Row to be used in one
// instance of a Table class.
$bugs = new Bugs(array('rowClass' => 'MyRow'));

Row initialization

If application-specific logic needs to be initialized when a row is constructed, you can select to move your tasks to the init() method, which is called after all row metadata has been processed. This is recommended over the __construct() method if you do not need to alter the metadata in any programmatic way.

Example 315. Example usage of init() method

<?php
class MyApplicationRow extends Zend_Db_Table_Row_Abstract
{
    protected 
$_role;

    public function 
init()
    {
        
$this->_role = new MyRoleClass();
    }
}

Defining Custom Logic for Insert, Update, and Delete in Zend_Db_Table_Row

The Row class calls protected methods _insert(), _update(), and _delete() before performing the corresponding operations INSERT, UPDATE, and DELETE. You can add logic to these methods in your custom Row subclass.

If you need to do custom logic in a specific table, and the custom logic must occur for every operation on that table, it may make more sense to implement your custom code in the insert(), update() and delete() methods of your Table class. However, sometimes it may be necessary to do custom logic in the Row class.

Below are some example cases where it might make sense to implement custom logic in a Row class instead of in the Table class:

Example 316. Example of custom logic in a Row class

The custom logic may not apply in all cases of operations on the respective Table. You can provide custom logic on demand by implementing it in a Row class and creating an instance of the Table class with that custom Row class specified. Otherwise, the Table uses the default Row class.

You need data operations on this table to record the operation to a Zend_Log object, but only if the application configuration has enabled this behavior.

<?php
class MyLoggingRow extends Zend_Db_Table_Row_Abstract
{
    protected function 
_insert()
    {
        
$log Zend_Registry::get('database_log');
        
$log->info(Zend_Debug::dump($this->_data,
                                    
"INSERT: $this->_tableClass",
                                    
false)
                  );
    }
}

// $loggingEnabled is an example property that depends
// on your application configuration
if ($loggingEnabled) {
    
$bugs = new Bugs(array('rowClass' => 'MyLoggingRow'));
} else {
    
$bugs = new Bugs();
}

Example 317. Example of a Row class that logs insert data for multiple tables

The custom logic may be common to multiple tables. Instead of implementing the same custom logic in every one of your Table classes, you can implement the code for such actions in the definition of a Row class, and use this Row in each of your Table classes.

In this example, the logging code is identical in all table classes.

<?php
class MyLoggingRow extends Zend_Db_Table_Row_Abstract
{
    protected function 
_insert()
    {
        
$log Zend_Registry::get('database_log');
        
$log->info(Zend_Debug::dump($this->_data,
                                    
"INSERT: $this->_tableClass",
                                    
false)
                  );
    }
}

class 
Bugs extends Zend_Db_Table_Abstract
{
    protected 
$_name 'bugs';
    protected 
$_rowClass 'MyLoggingRow';
}

class 
Products extends Zend_Db_Table_Abstract
{
    protected 
$_name 'products';
    protected 
$_rowClass 'MyLoggingRow';
}

Define Inflection in Zend_Db_Table_Row

Some people prefer that the table class name match a table name in the RDBMS by using a string transformation called inflection.

Zend_Db classes do not implement inflection by default. See the chapter about extending inflection for an explanation of this policy.

If you prefer to use inflection, then you must implement the transformation yourself, by overriding the _transformColumn() method in a custom Row class, and using that custom Row class when you perform queries against your Table class.

Example 318. Example of defining an inflection transformation

This allows you to use an inflected version of the column name in the accessors. The Row class uses the _transformColumn() method to change the name you use to the native column name in the database table.

<?php
class MyInflectedRow extends Zend_Db_Table_Row_Abstract
{
    protected function 
_transformColumn($columnName)
    {
        
$nativeColumnName myCustomInflector($columnName);
        return 
$nativeColumnName;
    }
}

class 
Bugs extends Zend_Db_Table_Abstract
{
    protected 
$_name 'bugs';
    protected 
$_rowClass 'MyInflectedRow';
}

$bugs = new Bugs();
$row $bugs->fetchNew();

// Use camelcase column names, and rely on the
// transformation function to change it into the
// native representation.
$row->bugDescription 'New description';

You are responsible for writing the functions to perform inflection transformation. Zend Framework does not provide such a function.

Zend Framework