bnomei / kirby3-lapse

缓存任何数据直到设置的超时时间

4.1.4 2024-07-20 06:50 UTC

README

Release Downloads Build Status Coverage Status Maintainability Twitter

缓存任何数据直到设置的超时时间(带有自动键)。

商业用途


支持开源!

此插件是免费的,但如果您将其用于商业项目,请考虑赞助我或进行捐赠。
如果我的工作帮助您赚了钱,那么我得到一点回报似乎也是公平的,不是吗?

要善良。分享一点。谢谢。

- Bruno
 

安装

  • 解压缩master.zip到文件夹site/plugins/kirby3-lapse
  • 使用git submodule add https://github.com/bnomei/kirby3-lapse.git site/plugins/kirby3-lapse
  • 使用composer require bnomei/kirby3-lapse

使用案例

Kirby Pages-Cache可以缓存页面模板的输出。如果面板中的任何对象发生更改,它会使所有缓存文件无效。如果您不经常更改,这是一个不错的选择。但如果您经常更改,则需要一个知道哪些已更改以及哪些缓存需要使无效和哪些不需要的缓存。

有时您不能缓存整个页面,因为...

  • 它包含一个带有csrf散列的表单
  • 您使用内容安全策略头
  • 为无逻辑模板系统如handlebars构建和缓存数据,或
  • 您想从外部源(如API)缓存数据。

Lapse就是为了做这件事而构建的:**缓存任何数据直到设置的超时时间**。

使用示例

示例 1:get/set

$key = hash('xxh3', $page->url()); // unique key
// to delay data creation until need use a callback. do not use a plain array or object.
$data = function () {
    return [1, 2, 3];
};
$data = lapse($key, $data);

示例 2:自定义超时时间

$key = hash('xxh3', $page->url()); // unique key
$expires = 5; // in minutes. default: 0 aka infinite
$data = function () {
    return [1, 2, 3];
};
$data = lapse($key, $data, $expires);

示例 3:页面对象

$data = lapse(hash('xxh3', $page->url()), function () use ($kirby, $site, $page) {
    // create some data
    return [
        'author' => site()->author(),
        'title' => $page->title(),
        'text' => $page->text()->kirbytext(),
        'url' => $page->url(),
    ];
});

通过键删除

$key = hash('xxh3', $page->url()); // unique key
$wasRemoved = \Bnomei\Lapse::rm($key);

静态缓存助手 - lapseStatic()

有时您只需要为当前请求缓存一些东西,例如当重复使用Kirby的集合时。`lapseStatic()`助手使这类事情变得容易一些。生成数据的闭包只会调用一次,将其返回值设置为静态缓存,并且每次对集合的重复调用都会从静态内存数组中获取缓存的集合。

site/plugins/example/index.php

<?php

Kirby::plugin('bnomei/example', [
  'collections' => [
    // collections have to be a closure that is why it is wrapped in a fn
    'recent-courses' => fn() => lapseStatic(
        'recent-courses', // key 
        function () { // value
            return page('courses')->children()->listed()->sortBy('name')->limit(10);
        }
    )
]);

聪明的键

唯一但未修改

缓存使用字符串值作为键来存储和稍后检索数据。键通常是对象ID的散列以及一些元数据(如内容语言)。使用`$key = hash('xxh3', $page->url());`存储与页面相关的数据将工作得很好。如果您使用多语言设置,它会处理语言,因为语言包含在URL中。但它只会过期,如果您提供固定时间或自己使它无效。

修改

解决方案是包括所有与数据相关的对象的修改时间戳。因此,如果您存储了一个带有渲染图像的页面对象的查询结果,则需要包括所有这些对象的修改时间戳。这将导致每次源更改时都会创建一个新的缓存。

基本

$keys = [ $page->url().$page->modified() ];
foreach($page->images() as $image) {
    $keys[] = $image->id().$image->modified();
}
$key = hash('xxh3', implode($keys));

对象

从本插件的版本2开始,您也可以转发这些对象中的任何一个,键会为您神奇地创建。

  • 页面对象
  • 文件对象和文件版本对象(即缩略图),
  • 集合或
  • 网站对象
$objects = [$page, $page->images()];
$data = lapse($objects, ...)

多语言支持

插件创建的键被标记为当前语言。您将获得每个语言不同的缓存值。

AutoID或BoostID

如果您使用AutoID插件Boost插件,则修改时间戳将几乎在零CPU成本下检索,而不会导致在磁盘上检查文件。

常见问题解答

默认无限缓存持续时间

除非您在调用lapse()时设置过期时间,否则缓存文件将永远不会失效。这是因为插件旨在与定义过期时间的键一起使用,例如$key = hash('xxh3', $page->id().$page->modified());

$expires = 5; // in minutes. default: 0 aka infinite
$data = lapse($key, $data, $expires);

当使用Memcache或APCu时,您需要限制创建的缓存的最大数量,因为默认情况下您有非常有限的64MB内存。您可以将限制设置为bnomei.lapse.indexLimit,例如300。但请注意,这会使写入缓存稍微慢一些,因为插件内部索引必须更新。

调试时无缓存

当Kirby的全局调试配置设置为true时,将清除整个插件缓存,不会创建任何缓存。这将使您的生活更轻松——相信我。

Kirby字段对象和序列化

插件使用对象的默认Kirby序列化,由于内存引用无论如何都会丢失,所有Kirby字段对象都是通过调用它们的->value()方法来存储的。文件缓存使用json格式。

从v1插件迁移

  • 已删除$force参数:使用适当的键。
  • 所有设置都已删除:它们不再需要,如上所述。

性能

使用crc32生成哈希值

xxh3是PHP 8.1中最快的非加密哈希算法。lapse的键不需要加密。

缓存驱动程序

为了最佳性能,请将全局缓存驱动程序设置为使用服务器内存而不是硬盘上的文件(即使在SSDs上)。Memcache或ApcuCache可以在大多数托管环境中激活,但默认情况下很少激活。还可以参阅上面解释的bnomei.lapse.indexLimit设置。我的Redis缓存驱动程序SQLite缓存驱动程序比其他缓存驱动程序更快,且没有内存限制。在其他所有情况下,使用非常快的PHP缓存驱动程序或APCu。

return [
  'cache' => [
    'driver' => 'apcu', // php, redis, sqlite
  ],
];

示例

// lapse v1 could already do this:
// store data until objects are modified with optional expire
$data = lapse(
    $page->id().$page->modified(),
    ['some', 'kind', 'of', 'data'],
    60*24*7 // one week
);

// now it can create magic cache keys from kirby objects
$data = lapse(
    $page, // key with modification date created by lapse based on object 
    function () use ($page) {
        return [
           'title' => $page->title(),
       ];
    }
);

// or from an collection of pages or files
$collection = collection('mycollection');
$data = lapse(
    $collection, // this will turn into a key taking modification date of all objects into consideration
    function () use ($collection) {
        return [ /*...*/ ];
    }
);

// or from an array combining all these
$data = lapse(
    ['myhash', $page, $page->children()->images(), $collection, $site], // will create key from array of objects
    function () use ($site, $page, $collection) {
        return [
            // will not break serialization => automatically store ->value() of fields
            'author' => $site->author(),
            'title' => $page->title(),
            'hero' => $page->children()->images()->first()->srcset()->html(),
            'count' => $collection->count(),
        ];
    }
);

// remove by dynamic key
$wasRemoved = \Bnomei\Lapse::rm(
    ['myhash', $page, $page->children()->images(), $collection, $site]
);

🏎️ 如果您使用autoid或boost,修改查找的成本几乎为零。

取消缓存

如果您想取消缓存,可以在闭包中抛出LapseCancelException。这将防止数据缓存并返回null

$data = lapse(
    $page,
    function () use ($page) {
        if ($page->isUnpublished()) {
            // do not cache unpublished pages
            throw new \Bnomei\LapseCancelException();
        }
        return $page->title()->value();
    }
);
// $data === null for unpublished pages

免责声明

本插件提供“原样”使用,不提供任何保证。使用时请自行承担风险,并在将其用于生产环境之前自行测试。如果您发现任何问题,请创建一个新的问题

许可协议

MIT

不建议在任何推广种族主义、性别歧视、恐同、动物虐待、暴力或其他任何形式仇恨言论的项目中使用此插件。

致谢

基于