++ Introduction
{{Doctrine_Cache}} offers an intuitive and easy-to-use query caching solution. It provides the following things:

* Multiple cache backends to choose from (including Memcached, APC and Sqlite)
* Advanced options for fine-tuning. {{Doctrine_Cache}} has many options for fine-tuning performance.

Initializing a new cache driver instance:

<code type="php">
$cache = new Doctrine_Cache_Memcache($options);
</code>

++ Drivers
+++ Memcache
Memcache driver stores cache records into a memcached server. Memcached is a high-performance, distributed memory object caching system. In order to use this backend, you need a memcached daemon and the memcache PECL extension.

<code type="php">
// memcache allows multiple servers
$servers = array('host' => 'localhost',
                 'port' => 11211,
                 'persistent' => true);

$cache = new Doctrine_Cache_Memcache(array('servers' => $servers,
                                           'compression' => false));
</code>

Availible options for Memcache driver:

||~ Option ||~ Data Type ||~ Default Value ||~ Description  ||
|| servers || array  || array(array('host' => 'localhost','port' => 11211, 'persistent' => true)) || An array of memcached servers ; each memcached server is described by an associative array : 'host' => (string) : the name of the memcached server, 'port' => (int) : the port of the memcached server, 'persistent' => (bool) : use or not persistent connections to this memcached server  ||
|| compression || boolean || false || true if you want to use on-the-fly compression  ||

+++ APC
The Alternative PHP Cache (APC) is a free and open opcode cache for PHP. It was conceived of to provide a free, open, and robust framework for caching and optimizing PHP intermediate code. 

The APC cache driver of Doctrine stores cache records in shared memory.

<code type="php">
$cache = new Doctrine_Cache_Apc();
</code>


+++ Db

Db caching backend stores cache records into given database. Usually some fast flat-file based database is used (such as sqlite).

Initializing sqlite cache driver can be done as above:

<code type="php">
$conn  = Doctrine_Manager::connection(new PDO('sqlite::memory:'));

$cache = new Doctrine_Cache_Sqlite(array('connection' => $conn));
</code>

++ Caching queries
+++ Introduction

Doctrine provides means for caching DQL queries. Caching DQL queries can greatly increase performance. Consider the standard workflow of DQL query execution:

# Init new DQL query
# Parse DQL query
# Build database specific SQL query
# Execute the SQL query
# Build the result set
# Return the result set

Now these phases can be very time consuming, especially phase 4 which sends the query to your database server. When Doctrine query cache is being used only the following phases occur:
# Init new DQL query
# If DQL query exists in cache return the cached result set, otherwise do normal phases 2...6 and save the result set into cache.

So not only does the DQL query cache skip the standard database query execution phases it also skips the building of the result set and parsing of the DQL query. You should always consider using query caching for queries that are issued often.

+++ Using a cache driver

You can set a connection or manager level cache driver by using Doctrine::ATTR_CACHE. Setting a connection level cache driver means that all queries executed with this connection use the specified cache driver whereas setting a manager level cache driver means that all connections (unless overridden at connection level) will use the given cache driver.

Setting a manager level cache driver:
<code type="php">
$manager = Doctrine_Manager::getInstance();

$manager->setAttribute(Doctrine::ATTR_CACHE, $cacheDriver);
</code>

Setting a connection level cache driver:
<code type="php">
$manager = Doctrine_Manager::getInstance();
$conn    = $manager->openConnection('pgsql://user:pass@localhost/test');

$conn->setAttribute(Doctrine::ATTR_CACHE, $cacheDriver);
</code>

Usually the cache entries are valid for only some time. You can set global value for how long the cache entries should be considered valid by using Doctrine::ATTR_CACHE_LIFESPAN.
<code type="php">
$manager = Doctrine_Manager::getInstance();

// set the lifespan as one hour (60 seconds * 60 minutes = 1 hour = 3600 secs)
$manager->setAttribute(Doctrine::ATTR_CACHE_LIFESPAN, 3600);
</code>
Now as we have set a cache driver for use we can make a DQL query to use it:
<code type="php">
$query = new Doctrine_Query();

// fetch blog titles and the number of comments
$query->select('b.title, COUNT(c.id) count')
      ->from('Blog b')
      ->leftJoin('b.Comments c')
      ->limit(10)
      ->useCache(true);
      
$entries = $query->execute();
</code>

+++ Fine-tuning

In the previous chapter we used global caching attributes. These attributes can be overriden at the query level. You can override the cache driver by calling useCache with a valid cacheDriver:

<code type="php">
$query = new Doctrine_Query();

$query->useCache(new Doctrine_Cache_Apc());
</code>

Also you can override the lifespan attribute by calling setCacheLifeSpan():

<code type="php">
$query = new Doctrine_Query();

// set the lifespan as half an hour
$query->setCacheLifeSpan(60 * 30);
</code>



