从 memcached 加载 json_encoded PHP 数组时出现 Unicode 错误
Unicode error when loading a json_encoded PHP array from memcached
我需要使用 python 将 PHP 关联数组传输到进一步处理。 python 代码但是使用 pylibmc 无法从 memcached 加载字符串,抛出此错误:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe0 in position 32: invalid continuation byte
我写了一个小测试器。 PHP 创建 memcached 数据的代码:
<?php
$mc = new Memcached();
$mc->addServer('localhost', 11211);
$data = array();
for ( $i = 0; $i < 100; $i++) {
$index = "ti" . $i;
$data += [$index => "test string $i"];
}
$mc->delete('test');
$mc->add('test', json_encode($data), 60);
$reverse = $mc->get('test');
echo "$reverse\n"; // prints {"ti0":"test string 0" ...... "ti99":"test string 99"} as expected
$reverse_array = json_decode($reverse, true);
echo $reverse_array['ti10'] . "\n";
//prints 'test string 10' as expected
?>
所以这可以很好地从 PHP 写入 memcached 并读回它。
在 python 方面,这是我用来读取它的代码:
#!/usr/bin/python
import pylibmc
import json
mc = pylibmc.Client(["127.0.0.1"], binary=True, behaviors={"cas": True, "tcp_nodelay": True,"ketama": True})
temp = json.loads(mc.get("test"))
当运行 python 代码时,这是我得到的输出:
Traceback (most recent call last):
File "./mctest.py", line 7, in <module>
temp = json.loads(mc.get("test")))
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe0 in position 32: invalid continuation byte
如果我在 PHP 中创建一个非关联数组并通过 memcached 共享它,一切正常。
我试过的另外两个选项:
添加 utf8_encode 以确保编码正确:
$mc->add('test', utf8_encode(json_encode($data)), 60);
将 JSON_UNESCAPED_UNICODE 添加到 json_encode 函数:
$mc->add('test', json_encode($data, JSON_UNESCAPED_UNICODE), 60);
两者在 python 一方产生相同的结果。
有点不知所措 - 欢迎任何想法!
在尝试确定通过 pymemcache 从 memcached 检索到的结果字符串的编码时,我发现该字符串看起来不像任何已知编码,我使用 chardet 和 cchardet 确认了这一点。
在 PHP 端进一步挖掘后,我发现 PHP memcached 模块通过压缩数据篡改了它保存到 memcached 的字符串!
解决方案是将此行添加到 /etc/php/7.2/cli/conf.d/25-memcached.ini 文件中:
memcached.compression_threshold=9999999999
现在数据进入python,这是它应该的!
我需要使用 python 将 PHP 关联数组传输到进一步处理。 python 代码但是使用 pylibmc 无法从 memcached 加载字符串,抛出此错误:
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe0 in position 32: invalid continuation byte
我写了一个小测试器。 PHP 创建 memcached 数据的代码:
<?php
$mc = new Memcached();
$mc->addServer('localhost', 11211);
$data = array();
for ( $i = 0; $i < 100; $i++) {
$index = "ti" . $i;
$data += [$index => "test string $i"];
}
$mc->delete('test');
$mc->add('test', json_encode($data), 60);
$reverse = $mc->get('test');
echo "$reverse\n"; // prints {"ti0":"test string 0" ...... "ti99":"test string 99"} as expected
$reverse_array = json_decode($reverse, true);
echo $reverse_array['ti10'] . "\n";
//prints 'test string 10' as expected
?>
所以这可以很好地从 PHP 写入 memcached 并读回它。
在 python 方面,这是我用来读取它的代码:
#!/usr/bin/python
import pylibmc
import json
mc = pylibmc.Client(["127.0.0.1"], binary=True, behaviors={"cas": True, "tcp_nodelay": True,"ketama": True})
temp = json.loads(mc.get("test"))
当运行 python 代码时,这是我得到的输出:
Traceback (most recent call last):
File "./mctest.py", line 7, in <module>
temp = json.loads(mc.get("test")))
UnicodeDecodeError: 'utf8' codec can't decode byte 0xe0 in position 32: invalid continuation byte
如果我在 PHP 中创建一个非关联数组并通过 memcached 共享它,一切正常。
我试过的另外两个选项:
添加 utf8_encode 以确保编码正确:
$mc->add('test', utf8_encode(json_encode($data)), 60);
将 JSON_UNESCAPED_UNICODE 添加到 json_encode 函数:
$mc->add('test', json_encode($data, JSON_UNESCAPED_UNICODE), 60);
两者在 python 一方产生相同的结果。
有点不知所措 - 欢迎任何想法!
在尝试确定通过 pymemcache 从 memcached 检索到的结果字符串的编码时,我发现该字符串看起来不像任何已知编码,我使用 chardet 和 cchardet 确认了这一点。
在 PHP 端进一步挖掘后,我发现 PHP memcached 模块通过压缩数据篡改了它保存到 memcached 的字符串!
解决方案是将此行添加到 /etc/php/7.2/cli/conf.d/25-memcached.ini 文件中:
memcached.compression_threshold=9999999999
现在数据进入python,这是它应该的!