0

我试图执行下一个命令。

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

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

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

我已将登录添加到 PredisPredis\Connection\StreamConnection::write()

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

我在控制台中观察输出:

*2
$6
SELECT
$1
0
---23---
*4
$7
HINCRBY
$27
sentiment_combined:positive
$9
рыжий кот
$1
1
---81---

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

4

2 回答 2

1

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

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

于 2016-04-27T15:24:04.463 回答
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' => '',
                     ]
                ]);
于 2018-05-12T23:16:15.447 回答