views:

71

answers:

2

Hi all,

First; On my development server (localhost; default XAMPP on OSX) everything works fine, though when I deploy the exact same code (and data) to the staging server (managed Apache2 on Redhat) it breaks.

I'm caching some data using Zend_Cache using the File backend and auto-serialization. Special characters used in the original data display fine, though when they are loaded from cache they're all garbled up.

Anyone got a clue?

PS. Instead of just a workaround, I'm looking for a way to understand what might go "wrong" on the staging server. What could possibly mess this up?

UPDATE The data I'm caching is UTF-8 encoded.

UPDATE When looking at the raw cache files (of a serialized array) there i See one big difference; The data cached on my localhost shows no newlines when the (identical) data cached on the staging server does show newlines.

UPDATE Local server runs PHP 5.3, staging server runs PHP 5.2.10

UPDATE Running on Zend FW 1.10.8

A: 

Can you check LC_LANG and other language variables? Apart from your problem :

I have problem with my cache files, between my hosting and local server (one debian, one ubuntu) I discovered the problem, when serializing \r causes problem. One system saves \r but ignores counting.

So I before serializing, remove all \r from the string. That removed!

nerkn
+3  A: 

Hi ! , I have almost identical state like you ,

development machine is windows + php 5.3

development machine is Linux + php 5.2.14

ZF version is 1.10

the only difference i had is : i used to add mb_internal_encoding("UTF-8"); in the bootstrap class

FYI , I used to cache text (arabic language ) from database all encoded UTF8 when i open the file i see the arabic text as expected .

UPDATE : 1- here is my complete initCache function just to make it clear

public function _initCache() {
        mb_internal_encoding("UTF-8");
        $frontendOptions = array(
            'automatic_serialization' => TRUE,
            'lifetime' => 86400
        );
        $backendOptions = array(
            'cache_dir' => APPLICATION_PATH . "/configs/cache/",
                ///'cache_dir' => sys_get_temp_dir(),
        );
        $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions);
        Zend_Db_Table_Abstract::setDefaultMetadataCache($cache);
        Zend_Registry::set("cache", $cache);
    }

Explanation : 1-Any php version earlier than PHP 6 doesn't have native support for UTF-8 , http://stackoverflow.com/questions/716703/what-is-coming-in-php-6

2-making php 5.3 or 5.2 deal with UTF8 by using ICONV or MB_STRING

simply by using var_dump(mb_internal_encoding());

you can tell that php using ISO-8859-1 internally ,

you can override it by var_dump(mb_internal_encoding("UTF-8"));

it would output true (it success to override the internal encoding )

to be honest i don't know if there is better solution or how bad it is ?? ,

if you had any better i would be happy to adopt it :)

UPDATE 2 in case you don't want to use that function , open this file "Zend/Cache/Backend/File.php" and go to the line 976 change this :

protected function _filePutContents($file, $string)
{

    $result = false;
    $f = @fopen($file, 'ab+');
    if ($f) {
        if ($this->_options['file_locking']) @flock($f, LOCK_EX);
        fseek($f, 0);
        ftruncate($f, 0);
        $tmp = @fwrite($f, $string);
        if (!($tmp === FALSE)) {
            $result = true;
        }
        @fclose($f);
    }
    @chmod($file, $this->_options['cache_file_umask']);
    return $result;
}

to be this :

protected function _filePutContents($file, $string)
{
    $string = mb_convert_encoding($string   , "UTF-8" , "ISO-8859-1"); // i didn't test it , use it at your own risk and i'd rather stick with the first solution 
    $result = false;
    $f = @fopen($file, 'ab+');
    if ($f) {
        if ($this->_options['file_locking']) @flock($f, LOCK_EX);
        fseek($f, 0);
        ftruncate($f, 0);
        $tmp = @fwrite($f, $string);
        if (!($tmp === FALSE)) {
            $result = true;
        }
        @fclose($f);
    }
    @chmod($file, $this->_options['cache_file_umask']);
    return $result;
}

i didn't test manually but it should work as expected

Glad it helped !

tawfekov
I've added the setting of mb_internal_encoding to the bootstrap on the staging server and flushed the cache. Now all data loaded from cache isn't garbled anymore.The weird thing is, after removing mb_internal_encoding and flushing cache again, the problem is still fixed.I'm gonna wait and see if it holds up. Might be a good idea to add it to the default bootstrap anyway.
Maurice
+1 good idea...!
Max
I've added it to the default bootstrapping class and it seems to be holding up. No more garbles in the data.Thanks for you answer!
Maurice
Cheers for the update, but I'd rather not change any code in ZF files. I could implement a custom backend based on Zend_Cache_Backend_File, but just setting the mb_internal_encoding() in the bootstrap would be be easier to maintain and might even prevent other character encoding issues not related to zend_cache.
Maurice
**UPDATE** after setting mb_internal_encoding(), no newlines on the staging server's cache files anymore.
Maurice
i'd rather stick with mb_internal_encoding("UTF-8"); and keep everything nice , tidy and less time consuming :P
tawfekov
@Maurice's update , sorry i was bit distracted yesterday , could you please show me some result from the cache
tawfekov