本篇內(nèi)容主要講解“PHP+redis緩存的方法是什么”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“PHP+Redis緩存的方法是什么”吧!
十余年的柴桑網(wǎng)站建設(shè)經(jīng)驗(yàn),針對(duì)設(shè)計(jì)、前端、開(kāi)發(fā)、售后、文案、推廣等六對(duì)一服務(wù),響應(yīng)快,48小時(shí)及時(shí)工作處理。成都全網(wǎng)營(yíng)銷(xiāo)推廣的優(yōu)勢(shì)是能夠根據(jù)用戶(hù)設(shè)備顯示端的尺寸不同,自動(dòng)調(diào)整柴桑建站的顯示方式,使網(wǎng)站能夠適用不同顯示終端,在瀏覽器中調(diào)整網(wǎng)站的寬度,無(wú)論在任何一種瀏覽器上瀏覽網(wǎng)站,都能展現(xiàn)優(yōu)雅布局與設(shè)計(jì),從而大程度地提升瀏覽體驗(yàn)。成都創(chuàng)新互聯(lián)從事“柴桑網(wǎng)站設(shè)計(jì)”,“柴桑網(wǎng)站推廣”以來(lái),每個(gè)客戶(hù)項(xiàng)目都認(rèn)真落實(shí)執(zhí)行。
有否想過(guò)PHP使用redis
作為緩存時(shí),如何能:
1.前后臺(tái)模塊共用Model層;
2.但是,不能每個(gè)Model類(lèi)都進(jìn)行緩存,這樣太浪費(fèi)Redis資源;
3.前后臺(tái)模塊可以自由決定從數(shù)據(jù)庫(kù)還是從緩存讀數(shù)據(jù);
4.沒(méi)有冗余代碼;
5.使用方便。
這里我們先展示實(shí)現(xiàn)的最終效果。
馬上安裝使用命令:
$ composer install yeszao/cache
假設(shè)在MVC框架中,model
層有一個(gè)Book
類(lèi)和一個(gè)getById
方法,如下:
class Book { public function getById($id) { return $id; } }
加入緩存技術(shù)之后,原來(lái)方法的調(diào)用方式和返回的數(shù)據(jù)結(jié)構(gòu)都不應(yīng)該改變。
所以,我們希望,最后的效果應(yīng)該是這樣的:
(new Book)->getById(100); // 原始的、不用緩存的調(diào)用方式,還是原來(lái)的方式,一般是讀取數(shù)據(jù)庫(kù)的數(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ù)的來(lái)源函數(shù),并且被引用方式完全統(tǒng)一,可謂一箭三雕。
其實(shí)實(shí)現(xiàn)起來(lái)也比較簡(jiǎn)單,就是使用PHP的魔術(shù)方法__call()方法。
這里簡(jiǎn)單說(shuō)明一下__call
方法的作用。
在PHP中,當(dāng)我們?cè)L問(wèn)一個(gè)不存在的類(lèi)方法時(shí),就會(huì)調(diào)用這個(gè)類(lèi)的__call()
方法。
(如果類(lèi)方法不存在,又沒(méi)有寫(xiě)__call()
方法,PHP會(huì)直接報(bào)錯(cuò))
假設(shè)我們有一個(gè)Book
類(lèi):
class Book { public function __call($name, $arguments) { echo '類(lèi)Book不存在方法', $name, PHP_EOL; } public function getById($id) { echo '我的ID是', $id, PHP_EOL; } }
當(dāng)調(diào)用存在的getName(50)
方法時(shí),程序打?。?strong>我的ID是50。
而如果調(diào)用不存在的getAge()
方法時(shí),程序就會(huì)執(zhí)行到A類(lèi)的__call()
方法里面,這里會(huì)打?。?strong>類(lèi)Book不存在方法getAge。
這就是__call
的原理。
接下來(lái)我們就利用__call()
方法的這種特性,來(lái)實(shí)現(xiàn)緩存策略。
從上面的例子,我們看到,__call()
方法被調(diào)用時(shí),會(huì)傳入兩個(gè)參數(shù)。
$name
:想要調(diào)用的方法名
$arguments
:參數(shù)列表
我們就可以在參數(shù)上面做文章。
還是以Book
類(lèi)為例,我們假設(shè)其原本結(jié)構(gòu)如下:
class Book { public function __call($name, $arguments) { // 待填充內(nèi)容 } public function getById($id) { return ['id' => $id, 'title' => 'PHP緩存技術(shù)' . $id]; } }
開(kāi)始之前,我們還確認(rèn)Redis的連接,這是緩存必須用到的,這里我們寫(xiě)個(gè)簡(jiǎn)單的單例類(lèi):
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; }
然后,我們開(kāi)始填充__call()
方法代碼,具體說(shuō)明請(qǐng)看注釋?zhuān)?/p>
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)作 // 的名稱(chēng)都是5個(gè)字符,這樣截取就非常高效。 $method = substr($name, 0, -5); $action = substr($name, -5); // 當(dāng)前調(diào)用的類(lèi)名稱(chēng),包括命名空間的名稱(chēng) $class = get_class(); // 生成緩存鍵名,$arguments稍后再加上 $key = sprintf('%s:%s:', str_replace('\\', '_', $class), $method); // 都用小寫(xiě)好看點(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中沒(méi)有數(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)了我們開(kāi)始時(shí)的效果。
在實(shí)際使用中,我們需要做一些改變,把這一段代碼歸入一個(gè)類(lèi)中,
然后在model層的基類(lèi)中引用這個(gè)類(lèi),再傳入Redis句柄、類(lèi)對(duì)象、方法名和參數(shù),
這樣可以降低代碼的耦合,使用起來(lái)也更靈活。
完整的代碼已經(jīng)放在Github上,請(qǐng)參考文章開(kāi)頭的參考地址。
到此,相信大家對(duì)“PHP+Redis緩存的方法是什么”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢(xún),關(guān)注我們,繼續(xù)學(xué)習(xí)!
當(dāng)前名稱(chēng):PHP+Redis緩存的方法是什么
轉(zhuǎn)載源于:http://bm7419.com/article14/jdepde.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、企業(yè)網(wǎng)站制作、軟件開(kāi)發(fā)、品牌網(wǎng)站設(shè)計(jì)、Google、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(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í)需注明來(lái)源: 創(chuàng)新互聯(lián)