italystrap/storage

ItalyStrap 的存储库

1.0.1 2023-04-25 16:11 UTC

This package is auto-updated.

Last update: 2024-09-15 18:30:57 UTC


README

Test Application Latest Stable Version Total Downloads Latest Unstable Version License PHP from Packagist Mutation testing badge

WordPress 存储API - 面向对象的封装。本包提供了WordPress Transients、缓存、选项和ThemeMods的API。

目录

安装

使用Composer是最好的方式来使用这个包

composer require italystrap/storage

本包遵循SemVer规范,并且在次要版本之间将完全向后兼容。

介绍

这个库的目的是什么?

首先的思路是拥有一个通用的API,用于WordPress中所有存储系统,例如WordPress缓存APIWordPress Transients APIWordPress选项APIWordPress主题修改API等。这些库试图将一些具有相似行为的WordPress API统一到一个框架下。这意味着你可以扩展这个库的API来创建自己的存储系统。例如,你可以使用这个API处理元数据、文章元数据、用户元数据等。

为什么这个库叫“存储”?

在这里,“存储”一词用于指代存储在数据库表或文件中,以及在内存中的数据,如数组或对象,但在这些情况下,你可能需要创建自己的类。

现在在这个库中,你可以找到用于“选项”(或类似)的API和用于“缓存”(或类似)的API,你可能想知道为什么,第一个原因是,我已经有一个名为Cache的库,用于实现PSR-6和PSR-16,所以我不想重复名称,第二个原因是将WordPress中可以找到的所有类似存储系统分组在一起。

目前,这个库中使用的接口放置在另一个名为Common的库中,因为我想要在其他库中使用它们。

为什么是面向对象的封装方式?

使用这个库,你可以在你的类中注入所需的存储系统,而不是将你的类耦合到特定的存储系统,并通过模拟这个库来简化你的类的测试。

这个API从PSR-16中吸取了一些概念,并且它也可以应用于WordPress中的其他类型的存储系统,而不仅仅是Transients、Options、Mods等,例如,你可以使用这个API处理元数据、文章元数据、用户元数据等。

如果你需要一个用于WordPress Transients和缓存的PSR-6或PSR-16实现,可以使用ItalyStrap\Cache包,并将此库用作驱动程序,记住,你可以使用扩展Cache API的驱动程序,但不能使用Store API,因为Store API中缺少TTL。

将其视为WordPress Transients API、Options API、Mods API等的一个包装器,但有一些不同之处。

与WordPress Transients API、Options API、Mods API等的不同之处

最重要的区别是Class::get()方法的返回值。在WordPress的Transients API、Cache API、Option API等中,\get_*()函数在结果不存在或已过期时返回false。在这个API中,如果结果不存在或已过期,Class::get()方法将返回null

我不是很喜欢null值,但它遵循PSR-16规范,其中没有值表示null,而false可能是一个有效的值。

过期时间

StoreInterface::class没有过期时间,所以可以把它想象成一个永远不会过期的永久存储系统。

如果您需要存储一个特定时间内的值,应使用CacheInterface::class

第二个区别是,如果您提供0作为过期时间,这意味着您将存储该值0秒,而不是像WordPress那样永久存储。

您可能会问为什么?

因为如果您提供0秒作为过期时间,您实际上是在告诉库存储该值0秒而不是永久存储(如果有一个很好的理由这样做,请提交一个问题,我们将讨论这个问题)。如果您想永久存储一个值,只需使用不带过期时间的::set()方法,或者将过期时间传递为null,内部库将过期时间设置为1年,而1年应该足够用于永久值。

过期时间和Cache API

另一个重要的事情是,如果您使用Cache::class并传递任何值作为过期时间,这将没有任何效果,因为Cache::classWordPress Cache API的包装器,而默认API不会持久化任何数据。如果您安装了其他提供Cache API另一个实现的插件,请参阅该插件的文档以了解它是否支持过期时间。

为什么存在::update()方法?

您可能会问为什么存在::update()方法,实际上您可以使用::set()方法来更新一个值,WordPress Cache API中只有一个\wp_cache_replace()函数返回false(如果值不存在),还有一个\update_option()函数,它会在值不存在时创建一个值,所以我决定创建一个::update()方法,以使其他存储系统的行为与Option API相同。

这是一个错误的决定吗?我留给您决定:-D我认为这个方法是不必要的,但我决定把它留下来以保持完整性。

Class::delete()方法的返回值

在WordPress中,API之间没有真正的标准(f**k),Class::delete()方法就是另一个例子。唯一不返回任何内容的函数是\remove_theme_mod(),其他所有函数在值被删除时返回true,如果值不存在,则返回false。现在,为了使其更接近PSR-16规范,Class::delete()方法在值被删除时返回true,如果值不存在,唯一返回false的方法是提供一个空字符串作为键。

基本用法

请记住,用于transients的键的最大长度为<=172个字符,超过这个长度将引发异常。

Option API

declare(strict_types=1);

namespace Your\Namespace;

use ItalyStrap\Storage\Option;

$option = new Option();

$option->set('my_option', 'my_value');

'my_value' === $option->get('my_option'); // true

$option->delete('my_option');

null === $option->get('my_option'); // true

$option->setMultiple([
    'option_1'	=> 'value_1',
    'option_2'	=> 'value_2',
]);

[
    'option_1'	=> 'value_1',
    'option_2'	=> 'value_2',
] === $option->getMultiple([
    'option_1',
    'option_2',
]); // true

$option->deleteMultiple([
    'option_1',
    'option_2',
]);

null === $option->get('option_1'); // true
null === $option->get('option_2'); // true

Mods API

declare(strict_types=1);

namespace Your\Namespace;

use ItalyStrap\Storage\Mods;

$mods = new Mod();

$mods->set('my_mod', 'my_value');

'my_value' === $mods->get('my_mod'); // true

$mods->delete('my_mod');

null === $mods->get('my_mod'); // true

$mods->setMultiple([
    'mod_1'	=> 'value_1',
    'mod_2'	=> 'value_2',
]);

[
    'mod_1'	=> 'value_1',
    'mod_2'	=> 'value_2',
] === $mods->getMultiple([
    'mod_1',
    'mod_2',
]); // true

$mods->deleteMultiple([
    'mod_1',
    'mod_2',
]);

null === $mods->get('mod_1'); // true
null === $mods->get('mod_2'); // true

$mods->clear();

来自WordPress Transients API文档

计时器常量

在WordPress环境中,如果您想设置过期时间,可以使用以下常量。

const MINUTE_IN_SECONDS  = 60; // (seconds)
const HOUR_IN_SECONDS    = 60 * MINUTE_IN_SECONDS;
const DAY_IN_SECONDS     = 24 * HOUR_IN_SECONDS;
const WEEK_IN_SECONDS    = 7 * DAY_IN_SECONDS;
const MONTH_IN_SECONDS   = 30 * DAY_IN_SECONDS;
const YEAR_IN_SECONDS    = 365 * DAY_IN_SECONDS;

WordPress Transients API的常见用法

这是您如何使用WordPress Transients API的一个示例。

if (false === ($special_data_to_save = \get_transient('special_data_to_save'))) {
    // It wasn't there, so regenerate the data and save the transient
    $special_data_to_save = ['some-key' => 'come value'];
    \set_transient('special_data_to_save', $special_data_to_save, 12 * HOUR_IN_SECONDS);
}

以下是与上面相同的示例,但使用了这个库。

declare(strict_types=1);

namespace Your\Namespace;

use ItalyStrap\Storage\Transient;
$transient = new Transient();

if (false === ($special_data_to_save = $transient->get('special_data_to_save'))) {
    // It wasn't there, so regenerate the data and save the transient
    $special_data_to_save = ['some-key' => 'come value'];
    $transient->set('special_data_to_save', $special_data_to_save, 12 * HOUR_IN_SECONDS);
}

Cache::class类相同。

declare(strict_types=1);

namespace Your\Namespace;

use ItalyStrap\Storage\Cache;

$cache = new Cache();

if (false === ($special_data_to_save = $cache->get('special_data_to_save'))) {
    // It wasn't there, so regenerate the data and save the transient
    $special_data_to_save = ['some-key' => 'come value'];
    $cache->set('special_data_to_save', $special_data_to_save, 12 * HOUR_IN_SECONDS);
}

Transients API

declare(strict_types=1);

namespace Your\Namespace;

use ItalyStrap\Storage\Transient;

$transient = new Transient();

/**
 * Ttl value must be in seconds
 */
$transient->set('my_transient', 'my_value', 60);

'my_value' === $transient->get('my_transient'); // true

$transient->delete('my_transient');

null === $transient->get('my_transient'); // true

$transient->setMultiple([
    'mod_1'	=> 'value_1',
    'mod_2'	=> 'value_2',
], 60);

[
    'mod_1'	=> 'value_1',
    'mod_2'	=> 'value_2',
] === $transient->getMultiple([
    'mod_1',
    'mod_2',
]); // true

$transient->deleteMultiple([
    'mod_1',
    'mod_2',
]);

null === $transient->get('mod_1'); // true
null === $transient->get('mod_2'); // true

Cache API

declare(strict_types=1);

namespace Your\Namespace;

use ItalyStrap\Storage\Cache;

$cache = new Cache();

/**
 * Ttl value must be in seconds
 */
$cache->set('my_cache', 'my_value', 60);

'my_value' === $cache->get('my_cache'); // true

$cache->delete('my_cache');

null === $cache->get('my_cache'); // true

$cache->setMultiple([
    'mod_1'	=> 'value_1',
    'mod_2'	=> 'value_2',
], 60);

[
    'mod_1'	=> 'value_1',
    'mod_2'	=> 'value_2',
] === $cache->getMultiple([
    'mod_1',
    'mod_2',
]); // true

$cache->deleteMultiple([
    'mod_1',
    'mod_2',
]);

null === $cache->get('mod_1'); // true
null === $cache->get('mod_2'); // true

高级用法

如何为Cache API和Transients API创建关键字

一个好的做法是在关键字前添加一些其他字符串,比如您的命名空间、类名、方法名等,您也可以使用常量,这将帮助您避免与其他插件或主题冲突。

一个简单的示例

declare(strict_types=1);

namespace Your\Namespace;

use ItalyStrap\Storage\CacheInterface;use phpDocumentor\Reflection\Types\Mixed_;

$cache = new Cache();

$your_class = new class($cache) {
    private $cache;
    private $prefix = 'your_namespace';

    public function __construct(CacheInterface $cache)
    {
        $this->cache = $cache;
    }

    public function getSomething(): mixed
    {
        $keyword = $this->prefix . __CLASS__ . __METHOD__;

        if (false === ($data = $this->cache->get($keyword))) {
            // It wasn't there, so regenerate the data and save the transient
            $data = ['some-key' => 'come value'];
            $this->cache->set($keyword, $data, 12 * HOUR_IN_SECONDS);
        }

        return $data;
    }
};

}

贡献

欢迎所有反馈/错误报告/拉取请求。

许可

版权所有(c)2019 Enea Overclokk,ItalyStrap

本代码遵循MIT许可。

致谢