italystrap / storage
ItalyStrap 的存储库
Requires
- php: >=7.4
- italystrap/common: ^1.0
Requires (Dev)
- codeception/module-asserts: ^1.0
- codeception/module-db: ^1.2
- codeception/module-phpbrowser: ^1.0
- dealerdirect/phpcodesniffer-composer-installer: ^1.0
- humanmade/psalm-plugin-wordpress: ^3.0.0-alpha1
- infection/codeception-adapter: ^0.4.1
- infection/infection: ^0.26.6
- inpsyde/wp-stubs: dev-main
- italystrap/debug: ^2.1
- lucatume/function-mocker-le: ^1.0
- lucatume/wp-browser: ^3.1
- phpbench/phpbench: ^1.2
- phpcompatibility/php-compatibility: ^9.3
- phpmetrics/phpmetrics: ^2.8
- phpspec/prophecy-phpunit: ^2.0
- rector/rector: ^0.15.17
- squizlabs/php_codesniffer: ^3.7
- vimeo/psalm: ^5.6
This package is auto-updated.
Last update: 2024-09-15 18:30:57 UTC
README
WordPress 存储API - 面向对象的封装。本包提供了WordPress Transients、缓存、选项和ThemeMods的API。
目录
安装
使用Composer是最好的方式来使用这个包
composer require italystrap/storage
本包遵循SemVer规范,并且在次要版本之间将完全向后兼容。
介绍
这个库的目的是什么?
首先的思路是拥有一个通用的API,用于WordPress中所有存储系统,例如WordPress缓存API、WordPress Transients API、WordPress选项API、WordPress主题修改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::class
是WordPress 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环境中,如果您想设置过期时间,可以使用以下常量。
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许可。