Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
485 views
in Technique[技术] by (71.8m points)

php - Zend_Cache: After loading cached data, character encoding seems messed up

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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 , https://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 !


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...