Zend_Cache:加载缓存数据后,字符编码似乎混乱

发布于 2024-09-29 07:39:48 字数 573 浏览 10 评论 0原文

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

我使用文件后端和自动序列化使用 Zend_Cache 缓存一些数据。 原始数据中使用的特殊字符显示正常,但从缓存加载时它们全都是乱码。

有人有线索吗?

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

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

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

更新 本地服务器运行 PHP 5.3,临时服务器运行 PHP 5.2.10

UPDATE 在 Zend FW 1.10.8 上运行

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

ゝ偶尔ゞ 2024-10-06 07:39:48

我和你有几乎相同的状态,

开发机器是windows + php 5.3

开发机器是Linux + php 5.2.14

ZF版本是1.10

我唯一的区别是:我曾经添加mb_internal_encoding("UTF-8") ; 在引导类

FYI 中,我用来缓存数据库中所有编码为 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-任何早于 PHP 6 的 php 版本都没有对 UTF-8 的本机支持,
https://stackoverflow.com/questions/716703/what-is-coming-in- php-6

2-使 php 5.3 或 5.2 通过使用 ICONV 处理 UTF8 MB_STRING

只需使用 var_dump(mb_internal_encoding( ));

你可以告诉php内部使用ISO-8859-1

你可以通过var_dump(mb_internal_encoding("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;
}

我没有手动测试,但它应该按预期工作

很高兴它有帮助!

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 !

戒ㄋ 2024-10-06 07:39:48

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

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

所以我在序列化之前,从字符串中删除所有 \r 。那个删除了!

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!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文