真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

PHPlaravel框架Redis門面的誤用

使用laravel的redis時候亂用Facades踩了一個坑。。。

創(chuàng)新互聯(lián)公司于2013年成立,先為羅山等服務建站,羅山等地企業(yè),進行企業(yè)商務咨詢服務。為羅山企業(yè)網(wǎng)站制作PC+手機+微官網(wǎng)三網(wǎng)同步一站式服務解決您的所有建站問題。

判斷Redis是否有某個key值得時候是可以這樣寫,

Redis::exists(key值)

因為使用了Redis門面,所以可以直接使用Redis::exists而不用先建立實例,就是文檔中介紹的“Facade 基類使用魔術方法 __callStatic() 從你的門面中調(diào)用解析對象”。

簡單說就是沒有exists這個靜態(tài)方法,使用的時候會調(diào)用__callStatic(),建立實例:

$instance = static::getFacadeRoot();

使用Redis時候沒有使用默認庫0,所以按照文檔上的例子指定服務,

代碼如下:

Redis::connection('users');
Redis::exists(key值)

這么做不能判斷key值是否存在,測試以后發(fā)現(xiàn)第二行Redis::exists連接的仍然是默認庫0。

亂用Facades踩到坑了!

我用的是laravel5.2,redis使用Predis。

雖然Redis的Facades是一個靜態(tài)代理,在使用時候"Redis::"也是靜態(tài)唯一的,BUT connection并不是一個靜態(tài)方法。

Redis對應的Facades底層類 Illuminate\Redis\Database,connection方法如下

    /**
     * Get a specific Redis connection instance.
     *
     * @param  string  $name
     * @return \Predis\ClientInterface|null
     */
    public function connection($name = 'default')
    {
        return Arr::get($this->clients, $name ?: 'default');
    }

返回redis的鏈接實例。

實際上$this->clients在Redis::調(diào)用__callStatic()建立實例的時候就已經(jīng)初始化,

    /**
     * Create a new Redis connection instance.
     *
     * @param  array  $servers
     * @return void
     */
    public function __construct(array $servers = [])
    {
        $cluster = Arr::pull($servers, 'cluster');
        $options = (array) Arr::pull($servers, 'options');
        if ($cluster) {
            $this->clients = $this->createAggregateClient($servers, $options);
        } else {
            $this->clients = $this->createSingleClients($servers, $options);
        }
    }

打印發(fā)現(xiàn) $this->clients 是將 redis的所有配置都初始化,當connection傳入配置名的時候選擇這個配置鏈接實例。

雖然Redis實例是靜態(tài)的,但是這個redis鏈接并不是。

Redis::exists()更是和connection()方法無關,redis門面調(diào)用__callStatic()后會執(zhí)行 Illuminate\Redis\Database 的exists方法,但是Database沒有這個方法,所以觸發(fā)__call()方法。

    /**
     * Dynamically make a Redis command.
     *
     * @param  string  $method
     * @param  array   $parameters
     * @return mixed
     */
    public function __call($method, $parameters)
    {
        return $this->command($method, $parameters);
    }

而command() 方法使用的是default配置,也就是說Redis::所有方法除了connection都是默認庫。

    /**
     * Run a command against the Redis database.
     *
     * @param  string  $method
     * @param  array   $parameters
     * @return mixed
     */
    public function command($method, array $parameters = [])
    {
        return call_user_func_array([$this->clients['default'], $method], $parameters);
    }

所以要使用非默認配置的同一個redis鏈接時候必須保存redis實例,

$redis = Redis::connection("user");
$redis->exists(key值);


$redis->exists 不會調(diào)用database的command方法,redis繼續(xù)使用connection選擇的初始化鏈接,不會選擇default配置。

這其實還涉及到Predis底層的實現(xiàn),已經(jīng)超出我的理解范圍。

看完代碼感覺還是有點暈。。。

反正Redis門面還是不要亂用。



分享標題:PHPlaravel框架Redis門面的誤用
路徑分享:http://weahome.cn/article/ihgcci.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部