成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

PHP使用redis作為緩存時(shí)怎么實(shí)現(xiàn)高效緩存

本篇內(nèi)容介紹了“PHP使用redis作為緩存時(shí)怎么實(shí)現(xiàn)高效緩存”的有關(guān)知識(shí),在實(shí)際案例的操作過程中,不少人都會(huì)遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

目前成都創(chuàng)新互聯(lián)公司已為成百上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站托管運(yùn)營(yíng)、企業(yè)網(wǎng)站設(shè)計(jì)、長(zhǎng)島網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長(zhǎng),共同發(fā)展。

是否想過PHP使用redis作為緩存時(shí),如何能:

  1. 前后臺(tái)模塊共用Model層;

  2. 但是,不能每個(gè)Model類都進(jìn)行緩存,這樣太浪費(fèi)Redis資源;

  3. 前后臺(tái)模塊可以自由決定從數(shù)據(jù)庫還是從緩存讀數(shù)據(jù);

  4. 沒有冗余代碼;

  5. 使用方便。
    這里我們先展示實(shí)現(xiàn)的最終效果。

最終的代碼和使用說明請(qǐng)移步Github:https://github.com/yeszao/php-redis-cache。

馬上安裝使用命令:

$ composer install yeszao/cache

經(jīng)過簡(jiǎn)單配置就可以使用,請(qǐng)參看Github的README說明。

1 最終效果

假設(shè)在MVC框架中,model層有一個(gè)Book類和一個(gè)getById方法,如下:

class Book
{
    public function getById($id)
    {
        return $id;
    }
}

加入緩存技術(shù)之后,原來方法的調(diào)用方式和返回的數(shù)據(jù)結(jié)構(gòu)都不應(yīng)該改變。

所以,我們希望,最后的效果應(yīng)該是這樣的:

(new Book)->getById(100);           // 原始的、不用緩存的調(diào)用方式,還是原來的方式,一般是讀取數(shù)據(jù)庫的數(shù)據(jù)。
(new Book)->getByIdCache(100);      // 使用緩存的調(diào)用方式,緩存鍵名為:app_models_book:getbyid: + md5(參數(shù)列表)
(new Book)->getByIdClear(100);      // 刪除這個(gè)緩存
(new Book)->getByIdFlush();         // 刪除 getById() 方法對(duì)應(yīng)的所有緩存,即刪除 app_models_book:getbyid:*。這個(gè)方法不需要參數(shù)。

這樣我們可以很清楚的明白自己在做什么,同時(shí)又知道數(shù)據(jù)的來源函數(shù),并且被引用方式完全統(tǒng)一,可謂一箭三雕。

其實(shí)實(shí)現(xiàn)起來也比較簡(jiǎn)單,就是使用PHP的魔術(shù)方法__call()方法。

2 __call()方法

這里簡(jiǎn)單說明一下__call方法的作用。

在PHP中,當(dāng)我們?cè)L問一個(gè)不存在的類方法時(shí),就會(huì)調(diào)用這個(gè)類的__call()方法。

(如果類方法不存在,又沒有寫__call()方法,PHP會(huì)直接報(bào)錯(cuò))

假設(shè)我們有一個(gè)Book類:

class Book
{
    public function __call($name, $arguments)
    {
        echo '類Book不存在方法', $name, PHP_EOL;
    }

    public function getById($id)
    {
        echo '我的ID是', $id, PHP_EOL;
    }
}

當(dāng)調(diào)用存在的getById(50)方法時(shí),程序打?。何业腎D是50。

而如果調(diào)用不存在的getAge()方法時(shí),程序就會(huì)執(zhí)行到A類的__call()方法里面,這里會(huì)打?。侯怋ook不存在方法getAge。

這就是__call的原理。

3 實(shí)現(xiàn)細(xì)節(jié)

接下來我們就利用__call()方法的這種特性,來實(shí)現(xiàn)緩存策略。

從上面的例子,我們看到,__call()方法被調(diào)用時(shí),會(huì)傳入兩個(gè)參數(shù)。

name:想要調(diào)用的方法名arguments:參數(shù)列表
我們就可以在參數(shù)上面做文章。

還是以Book類為例,我們假設(shè)其原本結(jié)構(gòu)如下:

class Book
{
    public function __call($name, $arguments)
    {
        // 待填充內(nèi)容
    }

    public function getById($id)
    {
        return ['id' => $id, 'title' => 'PHP緩存技術(shù)' . $id];
    }
}

開始之前,我們還確認(rèn)Redis的連接,這是緩存必須用到的,這里我們寫個(gè)簡(jiǎn)單的單例類:

class Common
{
    private static $redis = null;

    public static function redis()
    {
        if (self::$redis === null) {
            self::$redis = new \Redis('127.0.0.1');
            self::$redis->connect('redis');
        }
        return self::$redis;
}

然后,我們開始填充__call()方法代碼,具體說明請(qǐng)看注釋:

class Book
{
    public function __call($name, $arguments)
    {
        // 因?yàn)槲覀冎饕歉鶕?jù)方法名的后綴決定具體操作,
        // 所以如果傳入的 $name 長(zhǎng)度小于5,可以直接報(bào)錯(cuò)
        if (strlen($name) < 5) {exit('Method does not exist.');}// 接著,我們截取 $name,獲取原方法和要執(zhí)行的動(dòng)作,// 是cache、clear還是flush,這里我們?nèi)×藗€(gè)巧,動(dòng)作// 的名稱都是5個(gè)字符,這樣截取就非常高效。$method = substr($name, 0, -5);$action = substr($name, -5);// 當(dāng)前調(diào)用的類名稱,包括命名空間的名稱$class = get_class();// 生成緩存鍵名,$arguments稍后再加上$key = sprintf('%s:%s:', str_replace('\\', '_', $class), $method);// 都用小寫好看點(diǎn)$key = strtolower($key);switch ($action) {case 'Cache':// 緩存鍵名加上$arguments$key = $key . md5(json_encode($arguments));// 從Redis中讀取數(shù)據(jù)$data = Common::redis()->get($key);

                // 如果Redis中有數(shù)據(jù)
                if ($data !== false) {
                    $decodeData = json_decode($data, JSON_UNESCAPED_UNICODE);
                    // 如果不是JSON格式的數(shù)據(jù),直接返回,否則返回json解析后的數(shù)據(jù)
                    return $decodeData === null ? $data : $decodeData;
                }

                // 如果Redis中沒有數(shù)據(jù)則繼續(xù)往下執(zhí)行

                // 如果原方法不存在
                if (method_exists($this, $method) === false) {
                    exit('Method does not exist.');
                }

                // 調(diào)用原方法獲取數(shù)據(jù)
                $data = call_user_func_array([$this, $method], $arguments);

                // 保存數(shù)據(jù)到Redis中以便下次使用
                Common::redis()->set($key, json_encode($data), 3600);

                // 結(jié)束執(zhí)行并返回?cái)?shù)據(jù)
                return $data;
                break;

            case 'Clear':
                // 緩存鍵名加上$arguments
                $key = $key . md5(json_encode($arguments));
                return Common::redis()->del($key);
                break;

            case 'Flush':
                $key = $key . '*';

                // 獲取所有符合 $class:$method:* 規(guī)則的緩存鍵名 
                $keys = Common::redis()->keys($key);
                return Common::redis()->del($keys);
                break;

            default:
                exit('Method does not exist.');
        }
    }

    // 其他方法
}

這樣就實(shí)現(xiàn)了我們開始時(shí)的效果。

4 實(shí)際使用時(shí)

在實(shí)際使用中,我們需要做一些改變,把這一段代碼歸入一個(gè)類中,

然后在model層的基類中引用這個(gè)類,再傳入Redis句柄、類對(duì)象、方法名和參數(shù),

這樣可以降低代碼的耦合,使用起來也更靈活。

   

“PHP使用redis作為緩存時(shí)怎么實(shí)現(xiàn)高效緩存”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

當(dāng)前文章:PHP使用redis作為緩存時(shí)怎么實(shí)現(xiàn)高效緩存
URL分享:http://jinyejixie.com/article26/pgggjg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供品牌網(wǎng)站制作、電子商務(wù)、靜態(tài)網(wǎng)站、微信小程序、微信公眾號(hào)、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
德州市| 依兰县| 雅安市| 庄浪县| 巴中市| 缙云县| 瑞丽市| 黄陵县| 天祝| 获嘉县| 六盘水市| 旅游| 宕昌县| 报价| 久治县| 石泉县| 宜阳县| 茶陵县| 桃江县| 公主岭市| 靖宇县| 遵化市| 陕西省| 汾西县| 岫岩| 湖南省| 呼伦贝尔市| 凤阳县| 通辽市| 益阳市| 昌吉市| 四子王旗| 巧家县| 康乐县| 多伦县| 平顶山市| 东丰县| 福安市| 名山县| 弥渡县| 大埔县|