亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP laravel框架Redis門面的誤用

發布時間:2020-07-20 07:57:49 來源:網絡 閱讀:1085 作者:daweilang 欄目:web開發

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


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

Redis::exists(key值)

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

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

$instance = static::getFacadeRoot();


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

代碼如下:

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

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


亂用Facades踩到坑了!


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

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

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::調用__callStatic()建立實例的時候就已經初始化,

    /**
     * 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);
        }
    }

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

雖然Redis實例是靜態的,但是這個redis鏈接并不是。


Redis::exists()更是和connection()方法無關,redis門面調用__callStatic()后會執行 Illuminate\Redis\Database 的exists方法,但是Database沒有這個方法,所以觸發__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 不會調用database的command方法,redis繼續使用connection選擇的初始化鏈接,不會選擇default配置。

這其實還涉及到Predis底層的實現,已經超出我的理解范圍。


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

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


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

沅陵县| 略阳县| 民权县| 新乡县| 青岛市| 凤城市| 忻城县| 武陟县| 棋牌| 饶平县| 柘荣县| 吴旗县| 虹口区| 安阳市| 阿勒泰市| 张北县| 新民市| 扶余县| 河曲县| 墨江| 库伦旗| 敦煌市| 乐昌市| 龙陵县| 大冶市| 同江市| 房产| 镇原县| 成武县| 喀喇| 库尔勒市| 平昌县| 和顺县| 慈利县| 宝坻区| 黔西| 紫云| 新疆| 涞源县| 周口市| 天全县|