ZF-7366: Zend_Paginator does not use cached Zend_Db_Select correctly

Issue Type: Bug Created: 2009-07-23T07:51:16.000+0000 Last Updated: 2009-07-23T07:59:44.000+0000 Status: Resolved Fix version(s): Reporter: Michael Moussa (mmoussa) Assignee: Jurrien Stutterheim (norm2782) Tags: - Zend_Paginator

Related issues: - ZF-6989



Caching is not working correctly when using Zend_Paginator to paginate Zend_Db_Select results. The values are being cached (I can see the files in my cache location), but they are not being used.

The problem is that the cache IDs are being generated incorrectly.

<pre class="highlight">
class Dashboard_Feed extends Zend_Db_Table_Abstract
    protected $_name = 'FEED';
    protected $_primary = 'FEED_ID';

<pre class="highlight">
$feed = new Dashboard_Feed( Zend_Registry::get('db') );
$select = $feed->select()->order('FEED_TITLE' );

$paginator = Zend_Paginator::factory( $select );
$paginator->setCache( Zend_Registry::get('cache') );
$paginator->setCurrentPageNumber( $this->_getParam('page', 1) );

<pre class="highlight">
cache.frontend.type = "Core"
cache.frontend.options.automatic_serialization = true
cache.frontend.options.cache_id_prefix = "dashboard_"

cache.backend.type = "File"
cache.backend.options.cache_dir = APPLICATION_PATH "/../data/cache/"

Db adapter is Oracle

Upon first execution, zend_cache---dashboard_Zend_Paginator_1_81a9b1f25e24763494338baa43444b99 is creating in my cache directory - so far so good.

I make a change to one of the items in the DB and refresh. I should not see the change since the results are cached; however, I do see it. Zend_Paginator went back to the database to get the info.

I looked into the Zend_Paginator.php to attempt to get to the bottom of the issue. The problem can be observed in getItemsByPage(...). See the comments I inserted.

<pre class="highlight">
public function getItemsByPage($pageNumber)
    $pageNumber = $this->normalizePageNumber($pageNumber);

    if ($this->_cacheEnabled()) {
        // here, _getCacheId(...)  returns "Zend_Paginator_1_a479583744ccc3a9c4d653c390e7ff7f"
        $data = self::$_cache->load($this->_getCacheId($pageNumber));
        if ($data !== false) {
            return $data;

    $offset = ($pageNumber - 1) * $this->_itemCountPerPage;

    $items = $this->_adapter->getItems($offset, $this->_itemCountPerPage);

    $filter = $this->getFilter();

    if ($filter !== null) {
        $items = $filter->filter($items);

    if (!$items instanceof Traversable) {
        $items = new ArrayIterator($items);

    if ($this->_cacheEnabled()) {
        // here, _getCacheId(...)  returns "Zend_Paginator_1_81a9b1f25e24763494338baa43444b99"
        self::$_cache->save($items, $this->_getCacheId($pageNumber), array($this->_getCacheInternalId()));

    return $items;

As you can see, when the items are cached, the cache ID corresponds to what was created in my cache directory (obviously), but when Paginator tries to read the cache, it's looking for the wrong ID!

The source of the problem is that _getCacheInternalId() serializes the adapter to identify the cache entry.

<pre class="highlight">
protected function _getCacheInternalId()
    return md5(serialize($this->_adapter).$this->_itemCountPerPage);

Of course, the adapter's state is going to be different after results are retrieved vs before they are retrieved, so this mechanism cannot work. I saved the serialized value of the adapter from the first and second calls to _getInternalCacheId() to a file and did a diff... there are several differences.

The problem is greatly exacerbated if one is using Zend_Db_Profiler. I was using the profiler to determine if the cache was working correctly. Instead, Zend_Paginator was creating a brand new cache entry with a different ID each time every time I reloaded the page. Why? Well, the profiler contains performance information on the queries that have been run thus far. This information will be different from request to request 99.99% of the time. Different content = different serialization = different cacheId.

I would appreciate it if anybody can comment on this bug and perhaps queue up a resolution for the next ZF patch/release.

I am devising a workaround to use in my project and will post it here for the benefit of others who have encountered this problem.


Posted by julien PAULI (doctorrock83) on 2009-07-23T07:57:12.000+0000

Duplicates #ZF-6989 , even if it gives more informations (will be linked into #ZF-6989)

Posted by julien PAULI (doctorrock83) on 2009-07-23T07:59:44.000+0000

Please, get the patch attached to ZF-6989 and make a use case. We are actually looking for help to test that in order to provide a patch the better it could be.

Have you found an issue?

See the Overview section for more details.


© 2006-2018 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.