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

Caching Table Metadata

By default, Zend_Db_Table_Abstract queries the underlying database for table metadata whenever that data is needed to perform table operations. The table object fetches the table metadata from the database using the adapter's describeTable() method. Operations requiring this introspection include:

  • insert()

  • find()

  • info()

In some circumstances, particularly when many table objects are instantiated against the same database table, querying the database for the table metadata for each instance may be undesirable from a performance standpoint. In such cases, users may benefit by caching the table metadata retrieved from the database.

There are two primary ways in which a user may take advantage of table metadata caching:

  • Call Zend_Db_Table_Abstract::setDefaultMetadataCache() - This allows a developer to once set the default cache object to be used for all table classes.

  • Configure Zend_Db_Table_Abstract::__construct() - This allows a developer to set the cache object to be used for a particular table class instance.

In both cases, the cache specification must be either NULL (i.e., no cache used) or an instance of Zend_Cache_Core. The methods may be used in conjunction when it is desirable to have both a default metadata cache and the ability to change the cache for individual table objects.

Example 295. Using a Default Metadata Cache for all Table Objects

The following code demonstrates how to set a default metadata cache to be used for all table objects:

<?php
// First, set up the Cache
$frontendOptions = array(
    
'automatic_serialization' => true
    
);

$backendOptions  = array(
    
'cache_dir'                => 'cacheDir'
    
);

$cache Zend_Cache::factory('Core',
                             
'File',
                             
$frontendOptions,
                             
$backendOptions);

// Next, set the cache to be used with all table objects
Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);

// A table class is also needed
class Bugs extends Zend_Db_Table_Abstract
{
    
// ...
}

// Each instance of Bugs now uses the default metadata cache
$bugs = new Bugs();

Example 296. Using a Metadata Cache for a Specific Table Object

The following code demonstrates how to set a metadata cache for a specific table object instance:

<?php
// First, set up the Cache
$frontendOptions = array(
    
'automatic_serialization' => true
    
);

$backendOptions  = array(
    
'cache_dir'                => 'cacheDir'
    
);

$cache Zend_Cache::factory('Core',
                             
'File',
                             
$frontendOptions,
                             
$backendOptions);

// A table class is also needed
class Bugs extends Zend_Db_Table_Abstract
{
    
// ...
}

// Configure an instance upon instantiation
$bugs = new Bugs(array('metadataCache' => $cache));

Automatic Serialization with the Cache Frontend

Since the information returned from the adapter's describeTable() method is an array, ensure that the automatic_serialization option is set to TRUE for the Zend_Cache_Core frontend.

Though the above examples use Zend_Cache_Backend_File, developers may use whatever cache backend is appropriate for the situation. Please see Zend_Cache for more information.

Hardcoding Table Metadata

To take metadata caching a step further, you can also choose to hardcode metadata. In this particular case, however, any changes to the table schema will require a change in your code. As such, it is only recommended for those who are optimizing for production usage.

The metadata structure is as follows:

<?php
protected $_metadata = array(
    
'<column_name>' => array(
        
'SCHEMA_NAME'      => <string>,
        
'TABLE_NAME'       => <string>,
        
'COLUMN_NAME'      => <string>,
        
'COLUMN_POSITION'  => <int>,
        
'DATA_TYPE'        => <string>,
        
'DEFAULT'          => NULL|<value>,
        
'NULLABLE'         => <bool>,
        
'LENGTH'           => <string length>,
        
'SCALE'            => NULL|<value>,
        
'PRECISION'        => NULL|<value>,
        
'UNSIGNED'         => NULL|<bool>,
        
'PRIMARY'          => <bool>,
        
'PRIMARY_POSITION' => <int>,
        
'IDENTITY'         => <bool>,
    ),
    
// additional columns...
);

An easy way to get the appropriate values is to use the metadata cache, and then to deserialize values stored in the cache.

You can disable this optimization by turning of the metadataCacheInClass flag:

<?php
// At instantiation:
$bugs = new Bugs(array('metadataCacheInClass' => false));

// Or later:
$bugs->setMetadataCacheInClass(false);

The flag is enabled by default, which ensures that the $_metadata array is only populated once per instance.

Zend Framework