Laravel Laravel
  • 前言

    • 发行说明
    • 升级向导
    • 贡献导引
    • API 文档
  • 入门指南

    • 安装
    • 配置
    • 文件夹结构
    • Homestead
    • Valet
    • 部署
  • 架构思想

    • 请求生命周期
    • 服务容器
    • 服务提供者
    • Facades:门面
    • Contracts:契约
  • 基础功能

    • 路由
    • 中间件
    • CSRF 保护
    • 控制器
    • 请求
    • 响应
    • 视图
    • URL 生成
    • Session
    • 表单验证
    • 错误处理
    • 日志
  • 前端开发

    • Blade 模板
    • 本地化
    • 前端脚手架
    • 编译资源
  • 安全

    • 身份认证
    • API 身份认证
    • 授权
    • 邮件验证(new)
    • 加密
    • 哈希
    • 重置密码
  • 深入话题

    • Artisan 命令行
    • 广播
    • 缓存
    • 集合
    • 事件
    • 文件存储
    • 辅助函数
    • Mail
    • 消息通知
    • 扩展包开发
    • 队列
    • 任务调度
  • 数据库

    • 快速入门
    • 查询构造器
    • 分页
    • 数据库迁移
    • 数据填充
    • Redis
  • Eloquent ORM

    • 快速入门
    • 关联关系
    • Eloquent 集合
    • 修改器
    • API 资源
    • 序列化
  • 测试

    • 快速入门
    • HTTP 测试
    • 命令行测试(new)
    • 浏览器测试
    • 数据库测试
    • 测试模拟器Mocking
  • 官方扩展包

    • Cashier
    • Dusk浏览器测试(new)
    • Envoy部署工具
    • Horizon队列管理工具
    • Passport OAuth 认证
    • Scout全文搜索
    • Socialite社会化登录
    • Telescope 调试工具(new)
Icon

提示 您正在浏览旧版本的 Laravel 的文档. 请考虑将你的项目升级到 Laravel 11.x.

7 5

缓存系统
5.7
8.x 7.x 6.x 5.8 5.7 5.6 5.5 5.4 5.3 5.2 5.1

Laravel 5.7 中文文档 /

未匹配的标注
本文档最新版为 8.x,旧版本可能放弃维护,推荐阅读最新版!

缓存系统

  • 配置
    • 驱动的前提条件
  • 缓存的使用
    • 获取缓存实例
    • 从缓存中获取数据
    • 在缓存中存储数据
    • 删除缓存中的数据
    • 原子锁
    • Cache 辅助函数
  • 缓存标记
    • 写入被标记的缓存数据
    • 访问被标记的缓存数据
    • 移除被标记的缓存数据
  • 增加自定义缓存驱动
    • 编写驱动
    • 注册驱动
  • 事件

配置

Laravel 为各种后端缓存提供丰富而统一的 API, 其配置信息位于 config/cache.php 文件中。 在该文件中你可以指定应用默认使用哪个缓存驱动。 Laravel 支持当前流行的后端缓存, 例如 Memcached 和 Redis 。

缓存配置文件还包含各种其他选项, 这些选项都记录在文件中, 因此请确保阅读这些选项。 默认情况下, Laravel 配置为使用 file 缓存驱动, 它将序列化的缓存对象存储在文件系统中。 对于大型应用, 建议您使用更强大的驱动程序, 例如 Memcached 或 Redis。 你甚至可以为同一个驱动程序配置多个缓存配置。

驱动的前提条件

数据库

当使用 database 缓存驱动时, 你需要配置一个表来存放缓存数据。 下面是构建缓存数据表结构的 Schema 声明示例:

Schema::create('cache', function ($table) {
    $table->string('key')->unique();
    $table->text('value');
    $table->integer('expiration');
});

{tip} 你也可以使用 Artisan 命令 php artisan cache:table 来生成合适的迁移。

Memcached

使用 Memcached 驱动需要安装 Memcached PECL 扩展包 。 你可以把所有 Memcached 服务器都列在 config/cache.php 配置文件中:

'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) 或者使用 PECL 安装 PhpRedis PHP 扩展。

如需了解更多关于 Redis 的配置, 请参考 Laravel Redis 文档。

缓存的使用

获取缓存实例

Illuminate\Contracts\Cache\Factory 和 Illuminate\Contracts\Cache\Repository 契约 提供了 Laravel 缓存服务的访问机制。 Factory 契约为你的应用程序定义了访问所有缓存驱动的机制。 Repository 契约通常是由 cache 配置文件指定的默认缓存驱动实现的。

不过,你也可以使用 Cache Facade,我们将在后续的文档中介绍。Cache Facade 为 Laravel 缓存契约底层的实现提供了方便又简洁的方法:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\Cache;

class UserController extends Controller
{
    /**
     * 显示应用程序的所有用户的列表。
     *
     * @return Response
     */
    public function index()
    {
        $value = Cache::get('key');

        //
    }
}

访问多个缓存存储

使用 Cache Facade,你可以通过 store 方法来访问各种缓存存储。传入 store 方法的键应该对应 cache 配置信息文件中的 stores 配置数组中所列的存储之一:

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

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

从缓存中获取数据

Cache Facade 的 get 方法是用来从缓存中获取数据的方法。如果该数据不存在于缓存中,则该方法返回 null 。你也可以向 get 方法传递第二个参数,用来指定如果查找的数据不存在时你希望返回的默认值:

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

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

你甚至可以传递 Closure 作为默认值。如果指定的数据不存在于缓存中,将返回 Closure 的结果。传递闭包的方法可以允许你从数据库或其他外部服务中获取默认值:

$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 Facade 的 put 方法将数据存储到缓存中。当你在缓存中存放数据时,你需要使用第三个参数来设定缓存的过期时间:

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

除了以整数形式传递过期的分钟数,你还可以传递一个 DateTime 实例来表示该数据的过期时间:

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

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

只存储没有的数据

add 方法将只存储缓存中不存在的数据。如果存储成功,将返回 true,否则返回 false:

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

数据永久存储

forever 方法可于持久化将数据存储到缓存中。因为这些缓存数据不会过期,所以必须通过 forget 方法从缓存中手动删除它们:

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

{提示} 如果你使用 Memcached 驱动,当缓存数据量达到存储上限时,「永久存储」 的数据可能会被删除。

删除缓存中的数据

你可以使用 forget 方法从缓存中删除数据:

Cache::forget('key');

你也可以使用 flush 方法清空所有的缓存

Cache::flush();

{注意} 清空缓存的方法并不会考虑缓存前缀,会将缓存中的所有内容删除。因此在清除与其他应用程序共享的缓存时,请慎重考虑。

原子锁

{note} 使用该特性,应用必须使用 memcached 或 redis 缓存驱动作为应用默认缓存驱动。此外,所有服务器必须与同一中央缓存服务器进行通信。

原子锁允许对分布式锁进行操作而不必担心竞争条件。例如, Laravel Forge 使用原子锁来确保在一台服务器上每次只有一个远程任务在执行。你可以使用 Cache::lock 方法来创建和管理锁:

if (Cache::lock('foo', 10)->get()) {
    // 获取锁定10秒...

    Cache::lock('foo')->release();
}

get 方法也可以接收一个闭包。在闭包执行之后,Laravel 会自动释放锁:

Cache::lock('foo')->get(function () {
    // 锁无限期获取并自动释放...
});

您可以控制Laravel等待指定的秒数。如果在指定的时间限制内无法获取锁定,则会抛出:Illuminate\Contracts\Cache\LockTimeoutException

if (Cache::lock('foo', 10)->block(5)) {
    // 等待最多5秒后获取锁定...
}

Cache::lock('foo', 10)->block(5, function () {
    // 等待最多5秒后获取锁定...
});

Cache 辅助函数

除了可以使用 Cache Facade 或 cache 契约 外,你还可以使用全局辅助函数 cache 来获取和保存缓存数据。当 cache 函数只接收一个字符串参数的时候,它将会返回给定键对应的值:

$value = cache('key');

如果你向函数提供了一组键值对和过期时间,它会在指定时间内在缓存数据:

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

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

{tip} 如果在测试中使用全局函数 cache ,你可以使用 Cache::shouldReceive 方法就像 测试 Facade。

缓存标记

{note} 缓存标记不支持使用 file 或 database 缓存驱动。此外,当使用多个标记的缓存设置为「永久」时,类似 memcached 的缓存驱动性能最佳,它会自动清除旧的记录。

写入被标记的缓存数据

缓存标记允许你给缓存相关项进行标记,以便后续清除这些缓存值. 你可以通过传入标记名称的有序数组来访问标记的缓存。例如,我们可以使用标记的同时使用 put 方法设置缓存:

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

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

访问被标记的缓存数据

若要获取一个被标记的缓存数据,请将相同的有序标记数组传递给 tags 方法,然后调用 get 方法来获取你要检索的键:

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

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

移除被标记的缓存数据

你可以清空有单个标记或是一组标记的所有缓存数据。例如,下面的语句会删除被标记为 people、authors 或两者都有的缓存。 所以, Anne 和 John 都会从缓存被删除:

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

相比之下,下面的语句只会删除被标记为 authors 的缓存,所以 Anne 会被移除,但 John 不会:

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

增加自定义的缓存驱动

编写驱动

要创建自定义的缓存驱动程序,首先需要实现 Illuminate\Contracts\Cache\Store 契约。因此,MongoDB 的缓存实现看起来会像这样:

<?php

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 的连接来实现这些方法。 关于如何实现这些方法的示例,可以参阅框架源代码中的 Illuminate\Cache\MemcachedStore 。一旦完成契约的实现后,就可以像下面这样完成自定义驱动的注册了。

Cache::extend('mongo', function ($app) {
    return Cache::repository(new MongoStore);
});

{tip} 如果你不知道将缓存驱动代码放在哪,你可以在 app 目录下创建一个 Extensions 命名空间。但 Laravel 并没有硬性规定应用程序的结构,你可以根据自己的喜好自由组织你的应用程序。

注册驱动

要使用 Laravel 来注册自定义的缓存驱动,就要在 Cache Facade 上使用 extend 方法。对 Cache::extend 的调用可以在新的 Laravel 应用程序中自带的 App\Providers\AppServiceProvider 的 boot 方法中完成,或者你也可以创建自己的服务提供者来存放扩展,只是不要忘记在 config/app.php 的 provider 数组中注册服务提供者:

<?php

namespace App\Providers;

use App\Extensions\MongoStore;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\ServiceProvider;

class CacheServiceProvider extends ServiceProvider
{
    /**
     * 执行服务的注册后引导。
     *
     * @return void
     */
    public function boot()
    {
        Cache::extend('mongo', function ($app) {
            return Cache::repository(new MongoStore);
        });
    }

    /**
     * 在容器中注册绑定。
     *
     * @return void
     */
    public function register()
    {
        //
    }
}

传递给 extend 方法的第一个参数是驱动程序的名称。这将与 config/cache.php 配置文件的 driver 选项相对应。第二个参数是一个应该返回 Illuminate\Cache\Repository 实例的闭包。该闭包将传递一个 服务容器 的 $app 实例。

你的扩展程序注册后,需要将 config/cache.php 配置文件中的 driver 选项更新为你的扩展名称。

事件

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

/**
 * 应用程序的事件侦听器映射。
 *
 * @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',
    ],
];

本文章首发在 网站上。


上一篇 下一篇

成为Laravel合作伙伴

Laravel Partners是提供一流Laravel开发和咨询服务的精英商店。我们每个合作伙伴都可以帮助您制定一个精美,结构完善的项目.

我们的伙伴
Laravel
亮点
  • Our Team
  • 发布说明
  • 入门
  • 路由
  • Blade 模板
  • 身份验证
  • 用户授权
  • Artisan 控制台
  • 数据库
  • Eloquent ORM
  • 测试
资源
  • Laravel Bootcamp
  • Laracasts
  • Laravel News
  • Laracon
  • Laracon EU
  • Laracon India
  • Jobs
  • Forums
  • Trademark
  • 版本发布时间
  • 包开发
  • 命令行应用
  • TALL stack全栈开发
  • Blade UI Kit
  • 前端资源构建
伙伴
  • WebReinvent
  • Vehikl
  • Tighten
  • 64 Robots
  • Active Logic
  • Byte 5
  • Curotec
  • Cyber-Duck
  • DevSquad
  • Jump24
  • Kirschbaum
生态系统
  • Cashier
  • Dusk
  • Echo
  • Envoyer
  • Forge
  • Horizon
  • Nova
  • Octane
  • Sail
  • Sanctum
  • Scout
  • Spark
  • Telescope
  • Valet
  • Vapor

Laravel是一个具有表达力,优雅语法的Web应用程序框架。我们认为,发展必须是一种令人愉悦的创造力,才能真正实现。Laravel试图通过减轻大多数Web项目中使用的常见任务来减轻开发的痛苦.

Laravel是Taylor Otwell的商标.
Copyright © 2011-2025 Laravel中文网 LLC.

  • Twitter
  • GitHub
  • Discord
Laravel 全栈开发网 推荐使用阿里云 按Ctrl+D试试