taitava / php-cachedcall
这是一个简单的PHP特质,它使得在单个会话中缓存类方法调用结果变得容易。
Requires
- php: ^7.0
Requires (Dev)
This package is auto-updated.
Last update: 2024-09-24 23:39:58 UTC
README
这是一个简单的PHP特质,它使得在单个会话中缓存类方法调用结果变得容易。
适用于
- 缓存类方法调用。使用类私有属性进行缓存。
- 一个易于应用到您自己类中的特质。
- 简单而简洁 - 您只需几分钟就可以阅读和理解源代码,因此无需购买“猪在袋子里”。 :)
不适用于
- 不能用于在会话之间持久存储缓存。 在您的程序完成后,缓存将会消失。
- 由于特质设计,对类外函数进行缓存没有意义。但如果有需要,以后可以改进。
安装
使用composer
composer require "taitava/php-cachedcall:*"
然后在您的php应用程序中包含自动加载器
require_once "vendor/autoload.php";
用法
假设您有一个类 Page
,如下所示
require_once "vendor/autoload.php"; class Page { public $template = "page_template.html"; public $title; public $author; public $content; public $date; public function __construct($data) { foreach ($data as $key => $value) { $this->$key = $value; } } public static function getPageFromDB($id) { $data = ORM::table("Page")->getById($id); // ORM class is not defined in this example, but let's just pretend that it exists. :) return new self($data); } public function RenderContent() { $template = file_get_contents($this->template); $data = [ $this->title, $this->author, $this->content, $this->date, ]; // ... // Do some placeholder replacements to $template with $data here... // ... return $template } }
因此我们有两个方法(加上一个构造函数),我们希望缓存这两个方法,以避免在方法被多次调用时重复执行代码。我们的代码变为这样
require_once "vendor/autoload.php"; class Page { use Taitava\CachedCall\CachedCallTrait; // Apply the trait for this class. public $template = "page_template.html"; public $title; public $author; public $content; public $date; public function __construct($data) { foreach ($data as $key => $value) { $this->$key = $value; } } public static function getPageFromDB($id) { return static::cached_static_call(__METHOD__, func_get_args(), function ($id) { $data = ORM::table("Page")->getById($id); // ORM class is not defined in this example, but let's just pretend that it exists. :) return new self($data); }); } public function renderContent() { return $this->cached_call(__METHOD__, func_get_args() /* Actually this is an empty array because this method has no parameters. */, function () { $template = file_get_contents($this->template); $data = [ $this->title, $this->author, $this->content, $this->date, ]; // ... // Do some placeholder replacements to $template with $data here... // ... return $template }); } }
getPageFromDB()
是一个接受 $id
参数的静态方法。 renderContent()
方法是非静态的。在缓存非静态方法时,您应该调用 $this->cached_call()
方法,而在静态方法中,您应该调用 self::cached_static_call()
方法(或 static::cached_static_call()
)。记住,在需要时在中间添加 _static_
字词!
cached_call()
和 cached_static_call()
都有一组相似的参数
- string
$method_name
:从其中调用cached_call()
/cached_static_call()
的方法的名称。您可以使用__METHOD__
。缓存键的一部分。 - array
$parameters
:您想要传递给 $call 函数的任何参数。也将是缓存键的一部分。如果您不需要以任何方式更改参数,请使用func_get_args()
。 - callable
$call
:如果未找到具有匹配$method_name
+$parameters
缓存键的缓存,将调用的函数。
关于 $parameters
的限制
请注意,$parameters
只能包含
- 标量值:数字、字符串、布尔值。
- 具有可识别标识符字段的对象:
$ID
、$id
、$Id
或$iD
以下是不接受的
- 数组
- 没有识别id属性的对象
- 资源
- 我忘记列出的事物
此限制存在,因为生成缓存键需要是一个快速的过程,并且难以定义一个可靠的缓存键,例如,对于内容可以在方法调用之间变化的大数组。此外,由于对象需要具有id属性,因此对象支持相当有限。不支持 id()
或 getId()
方法。所有限制都可以在以后进行改进,如果想到更好的缓存键生成方式。
为了克服一些限制,例如,您可以绕过数组参数如下
require_once "vendor/autoload.php"; class Page { use Taitava\CachedCall\CachedCallTrait; // Apply the trait for this class. public $template = "page_template.html"; public $title; public $author; public $content; public $date; // ... public function doSomething(array $an_array) { $stringified_array = implode(",", $an_array); // Create a custom cache key. This can be done IF we know that the array is likely to be *small*. Be careful! $parameters = [$stringified_array]; return $this->cached_call(__METHOD__, $parameters, function () use ($an_array) { // ... // Do something with $an_array... // ... return $result }); } }
注意,我们避免了将 $an_array
传递给 cached_call()
,但我们通过 use ($an_array)
语句将其传递给我们的闭包函数!因此,我们能够在原始形式中使用该数组。
临时禁用缓存
如果您需要快速测试您的类而不使用缓存,您可以更改以下属性
require_once "vendor/autoload.php"; class Page { use Taitava\CachedCall\CachedCallTrait; public function method1($parameter) { $this->enable_cached_calls = false; // Disable cache $result = $this->cached_call(__METHOD__, func_get_args(), function () { // ... // Do something... // ... return $result }); $this->enable_cached_calls = true; // Re-enable cache return $result; } public static function method2($parameter) { static::$enable_cached_static_calls = false; // Disable cache $result = $this->cached_call(__METHOD__, func_get_args(), function () { // ... // Do something... // ... return $result }); static::$enable_cached_static_calls = true; // Re-enable cache } }
贡献
想法、错误报告和修复和新功能的拉取请求都是受欢迎的 :).
作者
Jarkko Linnanvirta