3

我在我的网站(Laravel 4.2)中使用 Redis 作为会话存储。有时我会遇到以下错误。我猜 ">" char 破坏了 setex 命令。

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '>'' in 

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command 'tml>''

production.ERROR: exception 'Predis\ServerException' with message 'ERR unknown command '</div>''

这些错误在生产服务器上很少发生,我无法重现它们。您知道为什么会发生这些错误以及如何防止它们吗?

key: laravel:xxxxxxxxxxxxxxx

value: s:217:"a:4:{s:6:"_token";s:40:"xxxxxxxxxxx";s:4:"lang";s:2:"fr";s:9:"_sf2_meta";a:3:{s:1:"u";i:1461777248;s:1:"c";i:1461777248;s:1:"l";s:1:"0";}s:5:"flash";a:2:{s:3:"old";a:0:{}s:3:"new";a:0:{}}}";

exception 'Predis\ServerException' with message 'ERR unknown command 'ml>'' in vendor/predis/predis/lib/Predis/Client.php:282

更新

我使用 redis 的代码示例。

    public function view($username = null)
    {
        $username = mb_strtolower($username);
        $redis = $this->getRedis();
        try{
            $view = $redis->get(User::getCacheKeyByUsername($username));
        }catch (\Exception $exception){
            $view = null;
        }
        if($view === null || Session::has("admin")){
            $user = User::where('username', '=', $username)->where("status", 1)->first();
            if (empty($user)) {
                return Redirect::to(Session::get("lang") . '/all');
            }
            $view = View::make("view", array("user" => $user));
            if(!Session::has("admin")){
                try{
                    $redis->setex(User::getCacheKeyByUsername($username), 3600, $view);
                }catch (\Exception $exception){
                    Log::error($exception->getMessage());
                }
            }
        }
        return $view;
    }
4

2 回答 2

1

好的,基本上我可以从你的错误日志中说什么:redis 不喜欢像<and这样的特殊字符>,所以你必须对它们进行编码。

检索时用于对数据进行htmlspecialchars编码和解码。htmlspecialchars_decode

于 2016-05-15T08:23:20.143 回答
0

你的 redis 客户端有问题。您无法重现它,因为错误不会发生在您的代码中,而是发生在客户端和redis服务器之间的TCP通信中。

我建议更新问题并提及您使用的是什么 redis 客户端模块。是predis吗?

如果您使用的是 unix,请尝试编译并安装 phpredis。它是 php 模块,我从来没有遇到过任何问题。


使用 telnet 进行复制

执行telnet host port并遵循说明:

正常请求GET a如下所示:

*2
$3
get
$1
a
$-1

现在考虑一下 - 要求gem a

*2
$3
gem
$1
a
-ERR unknown command 'gem'

协议有效,但命令“gem”无效。

现在考虑一下:

*1
$3
ml>
-ERR unknown command 'ml>'

这是你的错误。有效的协议,无效的命令。

或者考虑一下:

*2
$3
get
$1
<html>
$-1
-ERR unknown command 'ml>'

这又是你的错误。无效的strlen("<html>");

为什么这是 redis 客户端错误而不是用户错误:

许多 redis 客户端使用PHP magic methods.

这意味着如果您调用$redis->bla(),它们会提取“bla”部分及其参数并将它们转发到redis服务器。

然而你不能这样做$redis->ml>()。这将是语法错误。所以这是来自 redis 客户端的错误,而不是来自您的代码。

它也看起来像HTML. 看起来您正在将HTML数据存储在 redis 中。我只能猜测客户端没有计算strlen()count()发送错误信息“沿着 telnet 线路”。

于 2016-05-10T15:23:03.660 回答