Php Zend_缓存:加载缓存数据后,字符编码似乎混乱不堪

Php Zend_缓存:加载缓存数据后,字符编码似乎混乱不堪,php,zend-framework,character-encoding,zend-cache,Php,Zend Framework,Character Encoding,Zend Cache,第一,;在我的开发服务器(localhost;OSX上的默认XAMPP)上,一切正常,但当我将完全相同的代码(和数据)部署到登台服务器(Redhat上的托管Apache2)时,它会崩溃 我正在使用Zend_缓存缓存一些数据,使用文件后端和自动序列化。 原始数据中使用的特殊字符显示良好,但当从缓存加载时,它们都被弄乱了 有人有线索吗 另外,我正在寻找一种方法来理解登台服务器上可能出现的“错误”,而不仅仅是解决方法。什么会把事情搞砸 更新 我缓存的数据是UTF-8编码的 更新 当查看原始缓存文件(序

第一,;在我的开发服务器(localhost;OSX上的默认XAMPP)上,一切正常,但当我将完全相同的代码(和数据)部署到登台服务器(Redhat上的托管Apache2)时,它会崩溃

我正在使用Zend_缓存缓存一些数据,使用文件后端和自动序列化。 原始数据中使用的特殊字符显示良好,但当从缓存加载时,它们都被弄乱了

有人有线索吗

另外,我正在寻找一种方法来理解登台服务器上可能出现的“错误”,而不仅仅是解决方法。什么会把事情搞砸

更新 我缓存的数据是UTF-8编码的

更新 当查看原始缓存文件(序列化数组)时,我看到一个很大的区别; 当暂存服务器上缓存的(相同)数据显示换行时,本地主机上缓存的数据不显示换行

更新 本地服务器运行
PHP5.3
,临时服务器运行
PHP5.2.10

更新
在Zend FW 1.10.8上运行时,您可以检查LC_LANG和其他语言变量吗? 除了你的问题:

我的主机和本地服务器(一个debian,一个ubuntu)之间的缓存文件有问题 当序列化导致问题时,我发现了问题。一个系统保存但忽略计数


因此,在序列化之前,请删除字符串中的所有\r。那就删除了

你能检查LC_LANG和其他语言变量吗? 除了你的问题:

我的主机和本地服务器(一个debian,一个ubuntu)之间的缓存文件有问题 当序列化导致问题时,我发现了问题。一个系统保存但忽略计数


因此,在序列化之前,请删除字符串中的所有\r。那就删除了

我和你的状态几乎一样

开发机器是windows+PHP5.3

开发机器是Linux+PHP5.2.14

ZF版本是1.10

我唯一的不同是:我曾经添加
mb_内部编码(“UTF-8”)

仅供参考,我曾经缓存数据库中所有编码UTF8的文本(阿拉伯语) 当我打开文件时,我看到了预期的阿拉伯语文本

更新: 1-这里是我完整的initCache函数,只是想说明一下

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);
    }
说明: 1-任何早于PHP6的php版本都不支持UTF-8,

2-使PHP5.3或5.2使用or处理UTF8

只需使用
var_dump(mb_internal_encoding())

可以看出php在内部使用ISO-8859-1

您可以通过
var_dump(mb_内部_编码(“UTF-8”))覆盖它

它将输出true(覆盖内部编码成功)

老实说我不知道有没有更好的解决办法

如果你有更好的,我很乐意接受:)

更新2 如果您不想使用该功能, 打开此文件
“Zend/Cache/Backend/file.php”
并转到第976行 更改此项:

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;
}
为此:

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;
}
我没有手动测试,但它应该可以正常工作


很高兴它有帮助

我和你的状态几乎一样

开发机器是windows+PHP5.3

开发机器是Linux+PHP5.2.14

ZF版本是1.10

我唯一的不同是:我曾经添加
mb_内部编码(“UTF-8”)

仅供参考,我曾经缓存数据库中所有编码UTF8的文本(阿拉伯语) 当我打开文件时,我看到了预期的阿拉伯语文本

更新: 1-这里是我完整的initCache函数,只是想说明一下

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);
    }
说明: 1-任何早于PHP6的php版本都不支持UTF-8,

2-使PHP5.3或5.2使用or处理UTF8

只需使用
var_dump(mb_internal_encoding())

可以看出php在内部使用ISO-8859-1

您可以通过
var_dump(mb_内部_编码(“UTF-8”))覆盖它

它将输出true(覆盖内部编码成功)

老实说我不知道有没有更好的解决办法

如果你有更好的,我很乐意接受:)

更新2 如果您不想使用该功能, 打开此文件
“Zend/Cache/Backend/file.php”
并转到第976行 更改此项:

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;
}
为此:

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;
}
我没有手动测试,但它应该可以正常工作


很高兴它有帮助

这两个环境是否运行同一版本的Zend Framework?是的,所有代码都完全相同—包括使用的任何库。(ZF版本;1.10.8)这两个环境是否运行相同版本的Zend Framework?是的,所有代码都完全相同-包括使用的任何库。(ZF版本;1.10.8)我已将mb_内部_编码的设置添加到临时服务器上的引导程序中,并刷新了缓存。现在,从缓存加载的所有数据不再乱码。奇怪的是,在删除mb_内部编码并再次刷新缓存后,问题仍然得到了解决。我会等着看它能不能撑得住。无论如何,将它添加到默认引导中可能是个好主意。我已经将它添加到默认引导类中,它似乎可以正常工作。数据中不再有乱七八糟的东西。谢谢你的回答!欢迎更新,但我不想更改ZF文件中的任何代码。我可以基于Zend_Cache_backend_文件实现自定义后端,但只需在引导中设置mb_internal_encoding()将更易于维护,甚至可能防止与Zend_Cache无关的其他字符编码问题。设置mb_internal_encoding()后更新,屏幕上没有换行符