LoginSignup
0
1

More than 5 years have passed since last update.

FuelPHP上のRedisで配列を使う

Posted at

FuelPHPでRedisを使う場合、基本的にCoreのRedis_Dbを使う事になると思いますが、
MGETなどの可変長のデータを取り扱いたいときに配列がサポートされていないので今一使い辛いです。

他のredisライブラリを使うなどの方法があると思いますけど今回Coreを拡張してみます。
拡張のやり方自体は日本語サイト参照

拡張対象の関数

fuel/core/classes/redis/db.php
    /**
     * @param   $name
     * @param   $args
     * @return  $this|array
     * @throws  \RedisException
     */
    public function __call($name, $args)
    {
        // build the Redis unified protocol command
        array_unshift($args, strtoupper($name));
        $command = '*' . count($args) . CRLF;
        foreach ($args as $arg) {
            $command .= '$' . strlen($arg) . CRLF . $arg . CRLF;
        }
        // add it to the pipeline queue
        $this->queue[] = $command;
        if ($this->pipelined)
        {
            return $this;
        }
        else
        {
            return $this->execute();
        }
    }

主にredisサーバに送るデータを作ってる前半箇所を弄ります。

        array_unshift($args, strtoupper($name));
        $command = '*' . count($args) . CRLF;
        foreach ($args as $arg) {
            $command .= '$' . strlen($arg) . CRLF . $arg . CRLF;
        }

実装

拡張内容としては配列だった場合に配列を含めた要素をカウントしつつ配列そのものをデータとして使います。

fuel/app/classes/redis/db.php
    public function __call($name, $args)
    {
        // build the Redis unified protocol command
        $values = $args[0];
        $name = strtoupper($name);
        array_unshift($args, $name);
        $cnt = is_array($values) ? count($values) + 1 : count($args);
        $command = '*' . $cnt . CRLF;
        if (is_array($values)) {
            $command .= '$' . strlen($name) . CRLF . $name . CRLF;
            $args = $values;
        }
        foreach ($args as $arg) {
            $command .= '$' . strlen($arg) . CRLF . $arg . CRLF;
        }

    }

__callではなくそれぞれのredisコマンドに合わせて関数を作れば、
\$key=>\$valueに対応することでMSETとかもつかいやすくなるかと思います。

fuel/app/classes/redis/db.php
        public function mset($args)
        {
                $cnt =  count($args) * 2 + 1;
                $command = '*' . $cnt . CRLF;
                $command .= '$' . 4 . CRLF . 'MSET' . CRLF;
                foreach ($args as $key => $value) {
                        $command .= '$' . strlen($key) . CRLF . $key . CRLF;
                        $command .= '$' . strlen($value) . CRLF . $value . CRLF;
                }

                // add it to the pipeline queue
                $this->queue[] = $command;
                if ($this->pipelined)
                {
                        return $this;
                }
                else
                {
                        return $this->execute();
                }
        }

簡単な解説

FuelPHPのRedisはライブラリなどは使わずにソケット通信で実現しているので、
プロトコルに合わせた文字列を作る必要があります。
プロトコルっていうと何か凄く難しい印象があるけど、
Redisのプロトコルを調べてみたら日本語マニュアルの説明にある通り思ったより簡単でした。
Coreの実装を見るとプロトコルに合わせた文字列を作って送っているのがわかります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1