Predis。如何设置西里尔字母键?

Predis. How to set Cyrillic key?

我正在尝试执行下一个命令。

Redis::hincrby('sentiment_combined:positive', 'рыжий кот', 1);

此命令非常适用于拉丁键,例如 'orange cat'。但是 'рыжий кот' 我有下一个错误:

[Predis\Response\ServerException]         
ERR Protocol error: expected '$', got '�'  <

我添加了登录 Predis Predis\Connection\StreamConnection::write()

print_r($buffer);echo "---$written---\n";

然后我在控制台中观察输出:

*2

SELECT

0
---23---
*4

HINCRBY

sentiment_combined:positive

рыжий кот

1
---81---

Redis 支持 。如何克服 Predis 中的这个限制?

这里解决的问题:https://github.com/nrk/predis/issues/328

mbstring.func_overload = 6 中的原因 php.ini。必须是 mbstring.func_overload = 0.

use Predis\Response\Status as StatusResponse;

class MbStreamConnection extends \Predis\Connection\StreamConnection
{
    protected function write($buffer)
    {
        $socket = $this->getResource();

        $buffer = iconv('utf-8', 'windows-1251', $buffer);
        while (($length = mb_strlen($buffer, '8bit')) > 0)
        {
            $written = @fwrite($socket, $buffer, $length);

            if ($length === $written) {
                return;
            }

            if ($written === false) {
                $this->onConnectionError('Error while writing bytes to the server');
            }

            $buffer = substr($buffer, $written);
        }

        return;
    }

    /**
     * {@inheritdoc}
     */
    public function read()
    {
        $socket = $this->getResource();
        $chunk = fgets($socket);

        $chunk = iconv('windows-1251', 'utf-8', $chunk);

        if ($chunk === false || $chunk === '') {
            $this->onConnectionError('Error while reading line from the server.');
        }

        $prefix = $chunk[0];
        $payload = substr($chunk, 1, -2);

        switch ($prefix) {
            case '+':
                return StatusResponse::get($payload);

            case '$':
                $size = (int) $payload;

                if ($size === -1) {
                    return;
                }

                $bulkData = '';
                $bytesLeft = ($size += 2);

                do {
                    $chunk = fread($socket, min($bytesLeft, 4096));

                    if ($chunk === false || $chunk === '') {
                        $this->onConnectionError('Error while reading bytes from the server.');
                    }

                    $bulkData .= $chunk;
                    $bytesLeft = $size - mb_strlen($bulkData, '8bit');

                } while ($bytesLeft > 0);

                $tmp = mb_substr($bulkData, 0, -2);
                $tmp = iconv('windows-1251', 'utf-8', $tmp);
                return $tmp;

            case '*':
                $count = (int) $payload;

                if ($count === -1) {
                    return;
                }

                $multibulk = array();

                for ($i = 0; $i < $count; ++$i) {
                    $multibulk[$i] = $this->read();
                }

                return $multibulk;

            case ':':
                $integer = (int) $payload;
                return $integer == $payload ? $integer : $payload;

            case '-':
                return new ErrorResponse($payload);

            default:
                $this->onProtocolError("Unknown response prefix: '$prefix'.");

                return;
        }
    }
}

在连接参数中使用 MbStreamConnection

$client = new \Predis\Client('tcp://localhost:6379', [
                'scheme' => 'tcp',
                'host'   => 'localhost',
                'port'   => 6379,
                'connections' => [
                    'tcp' => 'MbStreamConnection'
                ],
                'parameters' => [
                    'password' => '',
                     ]
                ]);