ZF-11911: Long cache ids cause the file backend to produce too long file names

Description

We are generating our cache ids partly dynamic. In some cases they can be very long. If the get too long the file backend fails saving them as it creates the file names using the ids.

Different file systems have different length limits: http://en.wikipedia.org/wiki/…

This could be fixed on application level, but i believe it is better to fix this on framework level as the limitations on length are backend specific.

I've created a patch against the trunk (r24565) which introduces a new config option ("max_file_length"). This enables automatic file name shortening using the hashed cache id (to minimize the risk of id collisions). The option is disabled by default to keep BC. I suggest to set it to 255 as this seems to be the limit for most of the common file systems (ext2/3/4, ntfs, jfs, xfs, btrfs, ...).

A test case to reproduce the problem is also included.

### Eclipse Workspace Patch 1.0
#P ZendFramework-trunk
Index: library/Zend/Cache/Backend/File.php
===================================================================
--- library/Zend/Cache/Backend/File.php (Revision 24565)
+++ library/Zend/Cache/Backend/File.php (Arbeitskopie)
@@ -96,6 +96,7 @@
         'hashed_directory_umask' => 0700,
         'file_name_prefix' => 'zend_cache',
         'cache_file_umask' => 0600,
+        'max_file_length' => null,
         'metadatas_array_max_size' => 100
     );
 
@@ -863,6 +864,15 @@
     {
         $prefix = $this->_options['file_name_prefix'];
         $result = $prefix . '---' . $id;
+        
+        if (null !== $this->_options['max_file_length']) {
+            $path = $this->_path($result);
+            if (strlen($path . $result) > $this->_options['max_file_length']) {
+                $idHash = md5($result);
+                $result = substr($result, 0, $this->_options['max_file_length'] - strlen($path) - strlen($idHash)) . $idHash;
+            }
+        }
+        
         return $result;
     }
 
Index: tests/Zend/Cache/FileBackendTest.php
===================================================================
--- tests/Zend/Cache/FileBackendTest.php    (Revision 24565)
+++ tests/Zend/Cache/FileBackendTest.php    (Arbeitskopie)
@@ -120,7 +120,20 @@
         $res = $this->_instance->save('data to cache', 'foo', array('tag1', 'tag2'));
         $this->assertFalse($res);
     }
-
+    
+    /**
+     * Tests if long file names are prevented
+     *
+     * Depending on the FS there are different limits for the maximum file
+     * name length. Most FS' limit is 255 bytes or characters.
+     *
+     * @link http://en.wikipedia.org/wiki/…
+     */
+    public function testSaveWithVeryLongCacheId()
+    {
+        $cacheId = str_pad('', 300, 'a');
+        $this->_instance->setOption('max_file_length', 255);
+        $res = $this->_instance->save('data to cache', $cacheId);
+        $this->assertTrue($res);
+    }
 }
-
-

Comments

You will need to sign and submit a CLA before we can include your suggested fix in Zend Framework. See here: http://framework.zend.com/wiki/display/…

CLA is singed end sent.

The way you go doesn't work because it's changing the cache ids and methods like getIds no longer works as expected.

You can simply hash the cache id in your application before calling the cache.

On ZF2 you can get information about the backend how long the key can be.