Issues

ZF-7136: Zend_Cache_Backend change in 1.8.4 broke Zend_Locale_Data (and by extension, Zend_Date)

Description

We just upgraded from 1.8.2 to 1.8.4, and noticed that our Zend_Date call to toString was no longer working. We were getting an exception of "Could not determine temp directory, please specify a cache_dir manually" where it was working just great on 1.8.2 (and a downgrade to 1.8.2 made the exception go away again).


#0 /var/www/html/common/php/Zend-1.8.4/Cache/Backend.php(196): Zend_Cache::throwException('Could not deter...')
#1 /var/www/html/common/php/Zend-1.8.4/Cache/Backend/File.php(122): Zend_Cache_Backend->getTmpDir()
#2 /var/www/html/common/php/Zend-1.8.4/Cache.php(152): Zend_Cache_Backend_File->__construct(Array)
#3 /var/www/html/common/php/Zend-1.8.4/Cache.php(93): Zend_Cache::_makeBackend('File', Array, false, false)
#4 /var/www/html/common/php/Zend-1.8.4/Locale/Data.php(843): Zend_Cache::factory('Core', 'File', Array, Array)
#5 /var/www/html/common/php/Zend-1.8.4/Date.php(612): Zend_Locale_Data::getContent('en_US', 'month', Array)
#6 /var/www/html/common/php/Zend-1.8.4/Date.php(515): Zend_Date->_parseIsoToDate('MMM', 'en_US')
#7 /var/www/html/common/php/Zend-1.8.4/Date.php(488): Zend_Date->_toToken('MMM dSS, yyyy', 'en_US')
#8 /var/www/html/common/php/Zend-1.8.4/Date.php(412): Zend_Date->get('MMM dSS, yyyy', 'en_US')
#9 /var/www/path/to/our/view/script.phtml(116): Zend_Date->toString('M jS, Y', 'php')

I did some digging and found that the only change that could have caused this was the following:


--- Zend/Cache/Backend.php  (.../release-1.8.2/library) (revision 16310)
+++ Zend/Cache/Backend.php  (.../release-1.8.4/library) (revision 16310)
@@ -183,7 +183,9 @@
         if ($tempFile) {
            $dir = realpath(dirname($tempFile));
             unlink($tempFile);
-            return $dir;
+            if ($this->_isGoodTmpDir($dir)) {
+                return $dir;
+            }
         }
         if ($this->_isGoodTmpDir('/tmp')) {
            return '/tmp';

// ...
            if ($this->_isGoodTmpDir($dir)) {
                return $dir;
            }
        }
        if ($this->_isGoodTmpDir('/tmp')) {
            return '/tmp';
        }
        if ($this->_isGoodTmpDir('\\temp')) {
            return '\\temp';
        }
        Zend_Cache::throwException('Could not determine temp directory, plea
se specify a cache_dir manually');
    }
// ...

I don't know if the problem is that our temp directory really isn't a "GoodTmpDir", or whether "_isGoodTmpDir" is just failing. (I would guess the latter, though, since it was working fantastic before this change.)

To be honest, I wasn't even aware that Zend_Locale_Data (and by extension Zend_Date) was using a cache until this exception came up. Shouldn't all caching be disabled by default? I know that one can disable it by hand, but that shouldn't be necessary, unless it really offers some amazing difference to the use of the class that we didn't have before (like a 10x speed gain or something). My main concern, however, is that the code was working, but now it isn't.

Hopefully I've given enough information, but if not feel free to ask.

Comments

It does provide a performance boost of factor x15-20... returning one single cache entry instead of reading up to 3 xml files. But it will be reverted latest in 1.9 (within Locale_Data) as more people have a problem with non working cache that with performance on localization.

Thanks for your comments, Thomas. I've added a couple of these other issues you've mentioned to the "is related to" links.

IMHO, it's not a Zend_Cache issue (so I remove it as affected component). In your particular configuration, it's impossible to find automatically a tmp dir (working for Zend_Cache).

In 1.8.2, cache should fail silently (which was "bad").

In 1.8.4, if there is no automatically found tmp dir, an exception is thrown

IMHO, Zend_Locale_Data should intercept this exception and deactivate the cache (in this particular case).

@Fabien: Even if it was bad behaviour... by changing your code to throw a new exception you integrated a BC. Such changes are ONLY allowed within Minor Releases (1.9) and not within Bugfix Releases.

@Tianon: Use Zend_Locale::disableCache(true) to disable the caching within Zend_Locale

Update: I decided to dig a little bit more, and found that /tmp did NOT have read permission for others, which does explain why everything worked just fine before, but once we started checking for read permission it stopped working. Not that this really matters too much, but might be something to think about. (I also noticed that our /tmp directory is full of zend_cache---Zend_LocaleC_* type files, so it was definitely caching things properly, despite not being able to "read" the directory.)

As per internal discussion we decided NOT to erase the default caching. As with ZF 1.9 a migration note has been added to Zend_Locale.

Disabling the default cache is still possible with disableCache(true);