php redis 传递闭包,通过缓存构建高性能 Laravel 应用

通过缓存构建高性能 Laravel 应用

由 学院君 创建于3年前, 最后更新于 11个月前

版本号 #2

20678 views

9 likes

1 collects

c33ded3bfe6afc64dfb1b8bec54e42e1.png

配置

Laravel 为不同的缓存系统提供了统一的 API。缓存配置位于 config/cache.php。在该文件中你可以指定在应用中默认使用哪个缓存驱动。Laravel 开箱支持主流的缓存后端如 Memcached和 Redis 等。

缓存配置文件还包含其他文档化的选项,确保仔细阅读这些选项。默认情况下,Laravel 被配置成使用文件缓存,这会将序列化数据和缓存对象存储到文件系统。对于大型应用,建议使用内存缓存如 Memcached 或 APC,你甚至可以为同一驱动配置多个缓存配置。

驱动预备知识

数据库

使用 database 缓存驱动时,你需要设置一张表存储缓存项。下面是该表的 Schema 声明:

Schema::create('cache', function($table) {

$table->string('key')->unique();

$table->text('value');

$table->integer('expiration');

});

注:你还可以使用 Artisan 命令 php artisan cache:table 通过相应的 schema 生成迁移。

Memcached

使用 Memcached 缓存要求安装了Memcached PECL 包,即 PHP Memcached 扩展。你可以在配置文件 config/cache.php 中列出所有 Memcached 服务器:

'memcached' => [

[

'host' => '127.0.0.1',

'port' => 11211,

'weight' => 100

],

],

你还可以设置 host 选项为 UNIX socket 路径,如果你这样做,port 选项应该置为 0:

'memcached' => [

[

'host' => '/var/run/memcached/memcached.sock',

'port' => 0,

'weight' => 100

],

],

Redis

使用 Laravel 的 Redis 缓存之前,你需要通过 Composer 安装 predis/predis 包(~1.0)。

想要了解更多关于 Redis 的配置,查看 Larave 的 Redis 文档。

缓存使用

获取缓存实例

Illuminate\Contracts\Cache\Factory 和 Illuminate\Contracts\Cache\Repository 契约提供了访问 Laravel 缓存服务的方法。Factory 契约提供了所有访问应用定义的缓存驱动的方法。Repository 契约通常是应用中 cache 配置文件中指定的默认缓存驱动的一个实现。

不过,你还可以使用 Cache 门面,这也是我们在整个文档中使用的方式,Cache 门面提供了简单方便的方式对底层 Laravel 缓存契约实现进行访问:

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;

class UserController extends Controller

{

/**

* 显示应用所有用户列表.

*

* @return Response

*/

public function index()

{

$value = Cache::get('key');

//

}

}

访问多个缓存存储

使用 Cache 门面,你可以使用 store 方法访问不同的缓存存储器,传入 store 方法的键就是 cache 配置文件中 stores 配置数组里列出的相应的存储器:

$value = Cache::store('file')->get('foo');

Cache::store('redis')->put('bar', 'baz', 10);

从缓存中获取数据

Cache 门面的 get 方法用于从缓存中获取缓存项,如果缓存项不存在,返回 null。如果需要的话你可以传递第二个参数到 get 方法指定缓存项不存在时返回的自定义默认值:

$value = Cache::get('key');

$value = Cache::get('key', 'default');

你甚至可以传递一个闭包作为默认值,如果缓存项不存在的话闭包的结果将会被返回。传递闭包允许你可以从数据库或其它外部服务获取默认值:

$value = Cache::get('key', function() {

return DB::table(...)->get();

});

检查缓存项是否存在

has 方法用于判断缓存项是否存在,如果值为 null 或 false 该方法会返回 false:

if (Cache::has('key')) {

//

}

数值增加/减少

increment 和 decrement 方法可用于调整缓存中的整型数值。这两个方法都可以接收第二个参数来指明缓存项数值增加和减少的数目:

Cache::increment('key');

Cache::increment('key', $amount);

Cache::decrement('key');

Cache::decrement('key', $amount);

获取&存储

有时候你可能想要获取缓存项,但如果请求的缓存项不存在时给它存储一个默认值。例如,你可能想要从缓存中获取所有用户,或者如果它们不存在的话,从数据库获取它们并将其添加到缓存中,你可以通过使用 Cache::remember 方法实现:

$value = Cache::remember('users', $minutes, function() {

return DB::table('users')->get();

});

如果缓存项不存在,传递给 remember 方法的闭包被执行并且将结果存放到缓存中。

你还可以使用 rememberForever 方法从缓存中获取数据或者将其永久存储起来:

$value = Cache::rememberForever('users', function() {

return DB::table('users')->get();

});

获取&删除

如果你需要从缓存中获取缓存项然后删除,你可以使用 pull 方法,和 get 方法一样,如果缓存项不存在的话返回 null:

$value = Cache::pull('key');

在缓存中存储数据

你可以使用 Cache 门面上的 put 方法在缓存中存储数据。当你在缓存中存储数据的时候,需要指定数据被缓存的时间(分钟数):

Cache::put('key', 'value', $minutes);

除了传递缓存项失效时间,你还可以传递一个代表缓存项有效时间的 PHP Datetime 实例:

$expiresAt = Carbon::now()->addMinutes(10);

Cache::put('key', 'value', $expiresAt);

缓存不存在时存储数据

add 方法只会在缓存项不存在的情况下添加数据到缓存,如果数据被成功添加到缓存返回 true,否则,返回false:

Cache::add('key', 'value', $minutes);

永久存储数据

forever 方法用于持久化存储数据到缓存,这些值必须通过 forget 方法手动从缓存中移除:

Cache::forever('key', 'value');

注:如果你使用的是 Memcached 驱动,当缓存数据达到上限后永久存储的数据就会被移除。

从缓存中移除数据

你可以使用 Cache 门面上的 forget 方法从缓存中移除缓存项数据:

Cache::forget('key');

还可以使用 flush 方法清除所有缓存:

Cache::flush();

注:清除缓存并不管什么缓存键前缀,而是从缓存系统中移除所有数据,所以在使用这个方法时如果其他应用与本应用有共享缓存时需要格外注意。

缓存辅助函数

除了使用 Cache 门面或缓存契约,还可以使用全局的 cache 函数来通过缓存获取和存储数据。当带有一个字符串参数的 cache 函数被调用时,会返回给定键对应的缓存值(取值):

$value = cache('key');

如果你提供了键值对数组和一个过期时间给该函数,则会在指定的有效期内存储缓存值(存储):

cache(['key' => 'value'], $minutes);

cache(['key' => 'value'], Carbon::now()->addSeconds(10));

测试调用 cache 函数时,可以像测试门面一样使用 Cache::shouldReceive 方法。

缓存标签

注:缓存标签目前不支持 file 或 database 缓存驱动,此外,当使用多标签的缓存被设置为永久存储时,使用 memcached 驱动的缓存有着最佳性能表现,因为 Memcached 会自动清除陈旧记录。

存储被打上标签的缓存项

缓存标签允许你给相关缓存项打上同一个标签以便于后续清除这些缓存值,被打上标签的缓存可以通过传递一个被排序的标签数组来访问。例如,我们可以通过以下方式在添加缓存的时候设置标签:

Cache::tags(['people', 'artists'])->put('John', $john, $minutes);

Cache::tags(['people', 'authors'])->put('Anne', $anne, $minutes);

你可以给多个缓存项打上相同标签,这是没有数目限制的。

访问被打上标签的缓存项

要获取被打上标签的缓存项,传递同样的有序标签数组到 tags 方法然后使用你想要获取的key来调用 get 方法:

$john = Cache::tags(['people', 'artists'])->get('John');

$anne = Cache::tags(['people', 'authors'])->get('Anne');

移除被打上标签的数据项

你可以同时清除被打上同一标签/标签列表的所有缓存项,例如,以下语句会移除被打上 people 或 authors 标签的所有缓存:

Cache::tags(['people', 'authors'])->flush();

这样,上面设置的 Anne 和 John 缓存项都会从缓存中移除。

相反,以下语句只移除被打上 authors 标签的语句,所以只有 Anne 会被移除而 John 不会:

Cache::tags('authors')->flush();

添加自定义缓存驱动

编写驱动

要创建自定义的缓存驱动,首先需要实现 Illuminate\Contracts\Cache\Store 契约,所以,我们的 MongoDB 缓存实现看起来会像这样子:

namespace App\Extensions;

use Illuminate\Contracts\Cache\Store;

class MongoStore implements Store

{

public function get($key) {}

public function many(array $keys);

public function put($key, $value, $minutes) {}

public function putMany(array $values, $minutes);

public function increment($key, $value = 1) {}

public function decrement($key, $value = 1) {}

public function forever($key, $value) {}

public function forget($key) {}

public function flush() {}

public function getPrefix() {}

}

我们只需要使用一个 MongoDB 连接来实现其中的每一个方法,想要看如何实现每个方法的示例,可以参考 Laravel 底层源码 Illuminate\Cache\MemcachedStore,实现完成后,我们就可以完成自定义驱动注册:

Cache::extend('mongo', function($app) {

return Cache::repository(new MongoStore);

});

注:如果你在担心将自定义缓存驱动代码放到哪,可以在 app 目录下创建一个Extensions 命名空间。不过,记住 Laravel 并没有一个严格的应用目录结构,你可以基于你的需要自由的组织目录结构。

注册驱动

要通过 Laravel 注册自定义的缓存驱动,可以使用 Cache 门面上的 extend 方法。对 Cache::extend 的调用可以在 Laravel 自带的 App\Providers\AppServiceProvider 提供的 boot 方法中完成,或者,你也可以创建自己的服务提供者来存放扩展——只是别忘了在配置文件 config/app.php 中注册服务提供者到 providers 数组:

namespace App\Providers;

use App\Extensions\MongoStore;

use Illuminate\Support\Facades\Cache;

use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider

{

/**

* Perform post-registration booting of services.

*

* @return void

* @translator laravelacademy.org

*/

public function boot()

{

Cache::extend('mongo', function($app) {

return Cache::repository(new MongoStore);

});

}

/**

* Register bindings in the container.

*

* @return void

*/

public function register()

{

//

}

}

传递给 extend 方法的第一个参数是驱动名称。该值对应配置文件 config/cache.php 中的 driver 选项。第二个参数是返回 Illuminate\Cache\Repository 实例的闭包。该闭包中被传入一个 $app 实例,也就是服务容器的一个实例。

扩展被注册后,只需简单更新配置文件 config/cache.php 的 driver 选项为自定义扩展名称即可。

缓存事件

要在每次缓存操作时执行代码,你可以监听缓存触发的事件,通常,你可以将这些缓存处理器代码放到 EventServiceProvider 中:

/**

* The event listener mappings for the application.

*

* @var array

*/

protected $listen = [

'Illuminate\Cache\Events\CacheHit' => [

'App\Listeners\LogCacheHit',

],

'Illuminate\Cache\Events\CacheMissed' => [

'App\Listeners\LogCacheMissed',

],

'Illuminate\Cache\Events\KeyForgotten' => [

'App\Listeners\LogKeyForgotten',

],

'Illuminate\Cache\Events\KeyWritten' => [

'App\Listeners\LogKeyWritten',

],

];

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/529506.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

imclearboder matlab,Lucas

Lucas-Kanade跟踪算法是视觉跟踪中一个很经典的基于点的逐帧跟踪算法。起初这个算法是用来求解stero matching1的,后来经过Carlo Tomasi2和Jianbo Shi3等人的发展渐趋成熟。Jianbo Shi提出了一种筛选跟踪点特征的方法,使得特征的跟踪更可靠。Jean-Yves B…

matlab求勒让德多项式零点,有没有勒让德多项式导数 零点程序

求N1次勒让德多项式的m(m0,1,...)阶导数零点Matlab程序子程序:function xjp(N,alpha,beta)n1:N;a(1)(alphabeta2)/2;b(1)(beta-alpha)/2;a([2:N1])(2*nalphabeta1).*(2*nalphabeta2)./(2*(n1).*(nalphabeta1));b([2:N1])(alpha*alpha-beta*beta)*(2*nalphabeta1)./(…

js_long.php,protobuf.js 与 Long.js的使用详解

这次给大家带来protobuf.js 与 Long.js的使用详解,是急用protobuf.js 与 Long.js的注意事项有哪些,下面就是实战案例,一起来看一下。protobuf.js的结构和webpack的加载之后的结构很相似。这样的模块化组合是个不错的结构方式。1个是适应了不同…

oracle 存储过程设置回滚点,(转)oracle 存储过程事宜使用断点回滚 -savepoint

学习存储过程中使用断点回滚事务时,发现目前网络上存在一个问题,那就是使用断点回滚后,都忘记了一个很重要的事情,提交事务。虽然使用了断点回滚,但是断点回滚不像rollBack或commit一样结束当前事务,而使用…

oracle每季度补丁,Oracle 2020 年第四季度补丁发布

半个月前,也就是 10 月 20 日, Oracle 发布了今年最后一次补丁更新,那么很多人都想打最新的 PSU,理由是有被扫到各种漏洞,有的扫描工具着实太坑,这里就不用说了,前几天看到盖总发布的文章2020年…

路由器 刷 linux系统版本,在Linux下用tftp刷写路由器固件

(以Buffalo WHR-G300N V2路由器为例)以发行版Ubuntu为例(如果你在Windows下,可下载Ubuntu的ISO文件,再用wubi安装Ubuntu,可免去重新分区的麻烦),下载Buffalo WHR-G300N V2路由器的FTP版固件文件,放到Ubuntu的/home目录…

eval函数linux,Python中的eval()、exec()及其相关函数

刚好前些天有人提到eval()与exec()这两个函数,所以就翻了下Python的文档。这里就来简单说一下这两个函数以及与它们相关的几个函数,如globals()、locals()和compile():1. eval函数函数的作用:计算指定表达式的值。也就是说它要执行…

linux更改语言脚本,Linux shell脚本入门——shell语言脚本【CentOS】

认识脚本是使用一种特定的描述性语言,依据一定的格式编写的可执行文件。脚本语言又被称为扩建的语言, 或者动态语言, 是一种编程语言, 用来控制软件应用程序, 脚本通常是以文本 (ASCⅡ) 保存, 只是在被调用时进行解释或者编译。学习shell脚本的用途对于一个合格的系…

linux视图版怎么输入命令,分享在Linux命令下操作MySQL视图实例代码

视图VIEW命令简介:VIEW视图就是存储下来的SELECT语句数据1。创建视图命令格式:创建[或更换][ALGORITHM {UNDEFINED | MERGE | 不是Temptable}][DEFINER {user | 当前用户 }][SQL SECURITY {DEFINER | INVOKER}]VIEW view_name [(column_list)]AS selec…

宝塔linux 做负载均衡,利用BT宝塔面板做网站多服务器负载均衡图文教程

对于我们做网站的来说,如果流量大了,一台服务器肯定是不够的,接下来要考虑很多方面,比如动静分离、比如数据库异步,比如负载均衡等等。因为我们很多新手站长都用的是BT宝塔面板,下面虾皮路就介绍一下利用BT…

血型遗传关系c语言编程,根据血型遗传关系,编程实现:○1.输入

满意答案df4dfw5e562017.05.28采纳率:51% 等级:6已帮助:106人//仅作参考#include "stdio.h"#include "conio.h"#include "stdlib.h"#include "string.h"int studentNum 0;#define MAXSTUDENT (1…

android 通话结束广播,在Android中以编程方式结束通话

侃侃尔雅您无需成为系统应用程序。首先,com.android.internal.telephony在您的项目中创建包,并将其放入名为“ ITelephony.aidl” 的文件中:package com.android.internal.telephony; interface ITelephony { boolean endCall(); vo…

带nfc 的 android 华为,华为手机NFC功能,原来这么好用,不会用真可惜几千块钱了...

华为手机NFC功能,原来这么好用,不会用真可惜几千块钱了2019-05-06 17:40:259点赞12收藏6评论华为手机在国内也是数一数二的了,那么用华为手机的小伙伴,怎么能错过华为手机中NFC的功能呢?下面就随小编一起来了解一下吧。…

小米3升级android 6.0,可升级Android 6.0机型一览 小米手机亮了

前不久,Android M被谷歌正式确定为6.0系统,代号Marshmallow,预计年底前发布。而对于普通用户来说,最关心的就是自己的手机能不能升级。不过别着急,在此之前,我们不妨看看Android 6.0有哪些新功能。一、Andr…

浏览器兼容性怎么设置HTML,ie10浏览器中兼容性设置在哪里

之前ie浏览器一直被诟病的因素之一就是兼容性,不过ie10浏览器可以对兼容性进行设置,使得在兼容性视图中显示所有网站,具体怎么设置呢。下面由学习啦小编为你整理了ie10浏览器兼容性设置在哪里的解决方法,希望对你有帮助!ie10兼容性…

ksu7对讲机调频软件_科普 | 数字对讲机的群呼功能原理是什么?你了解多少?...

点击上方蓝字关注我们!无线对讲机群呼,是为了更好地达到1个数字对讲机能够同一时间跟多个数字对讲机实现语音通话。群呼跟单呼有很多共同之处,下面我们和大家来说说数字对讲机群呼与单呼不同点。当1个数字对讲机处在待机状态的情况下机要发动…

计算机学不学工程制图,大一,马上要考试了,不想再学工程制图了?

买买提烤串累计帮助了195人工科和文科思维方式是不一样的。本人刚好高中理科,大学学文的,而且一专业是中文,二专业管理。大多数工科的特点是靠努力为主的,除了特别难的那种专业,大多数工科的特点是这样的:除…

辅助驾驶等级_双AMR电机位置传感器,助力自动驾驶安全出行

好文章当然要分享啦~如果您喜欢这篇文章,请联系后台添加白名单,欢迎转载哟~在自动驾驶汽车快速发展的今天,汽车电气化趋势逐渐朝着半自动驾驶和全自动驾驶发展,尤其是,为了让电子转向助力(EPS)和电子制动系统满足必要的…

计算机怎么建立共享网络打印机共享,电脑如何连接局域网中的共享打印机—两种方法...

多台电脑而只有一台打印机的时候可以通过连接局域网的方式共享打印机,这样就不需要给每一台电脑都配上打印机了。下面是学习啦小编收集整理的电脑如何连接局域网中的共享打印机—两种方法,希望对大家有帮助~~电脑连接局域网中的共享打印机—两种方法操作…

html5 密码框明文,elementUI的密码框的密文和明文

基于elementui 框架的登录时密码框的明文和密文登录1、templatev-model.trim"ruleForm.password"placeholder"请输入密码":type"passw"clearableblur"onBlur">2、scriptdata(){return{icon: "el-input__icon el-icon-view&quo…