Ошибка Unicode при загрузке массива PHP json_encoded из memcached - PullRequest
0 голосов
/ 13 июня 2019

Мне нужно передать ассоциативный массив PHP для дальнейшей обработки с использованием Python.Однако код 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
?>

, так что это прекрасно работает, записывая в memcached из PHP и читая его обратно.

На стороне 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);

оба приводят к одинаковым результатам на стороне питона.

Потерялся здесь - любые идеи приветствуются!

1 Ответ

1 голос
/ 14 июня 2019

При попытке определить кодировку результирующей строки, извлеченной из memcached через pymemcache, мне пришло в голову, что строка не похожа ни на одну из известных кодировок, я подтвердил это, используя chardet и cchardet.

После еще нескольких копаний в конце PHP я обнаружил, что модуль memcached PHP фальсифицирует строки, которые он сохраняет в memcached, сжимая данные!

Решением было добавить эту строку в файл /etc/php/7.2/cli/conf.d/25-memcached.ini:

memcached.compression_threshold=9999999999

Теперь данные поступают в python, как и должно!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...