hyperf/docs/zh-hk/cache.md

286 lines
6.7 KiB
Markdown
Raw Normal View History

2019-03-08 12:04:46 +08:00
# Cache
2019-12-12 16:24:04 +08:00
[hyperf/cache](https://github.com/hyperf/cache) 提供了基於 `Aspect` 實現的切面緩存,也提供了實現 `Psr\SimpleCache\CacheInterface` 的緩存類。
2019-03-08 12:04:46 +08:00
2019-12-12 16:24:04 +08:00
## 安裝
2019-03-21 13:42:28 +08:00
```
composer require hyperf/cache
```
2019-12-12 16:24:04 +08:00
## 默認配置
2019-03-08 12:04:46 +08:00
2019-12-12 16:24:04 +08:00
| 配置 | 默認值 | 備註 |
2019-03-22 17:41:09 +08:00
|:------:|:----------------------------------------:|:---------------------:|
2019-12-12 16:24:04 +08:00
| driver | Hyperf\Cache\Driver\RedisDriver | 緩存驅動,默認為 Redis |
2019-05-24 15:37:46 +08:00
| packer | Hyperf\Utils\Packer\PhpSerializer | 打包器 |
2019-12-12 16:24:04 +08:00
| prefix | c: | 緩存前綴 |
2019-03-22 17:41:09 +08:00
2019-03-19 14:52:21 +08:00
```php
2019-03-08 12:04:46 +08:00
<?php
return [
'default' => [
'driver' => Hyperf\Cache\Driver\RedisDriver::class,
2020-06-16 01:43:41 +08:00
'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class,
2019-03-22 17:41:09 +08:00
'prefix' => 'c:',
2019-03-08 12:04:46 +08:00
],
];
2019-03-19 14:52:21 +08:00
```
2019-03-08 12:04:46 +08:00
## 使用
2019-10-12 18:25:18 +08:00
### Simple Cache 方式
2019-05-24 15:39:16 +08:00
2019-12-12 16:24:04 +08:00
Simple Cache 也就是 [PSR-16](https://www.php-fig.org/psr/psr-16/) 規範,本組件適配了該規範,如果您希望使用實現 `Psr\SimpleCache\CacheInterface` 緩存類,比如要重寫 `EasyWeChat` 的緩存模塊,可以直接從依賴注入容器中獲取 `Psr\SimpleCache\CacheInterface` 即可,如下所示:
2019-05-24 15:39:16 +08:00
```php
2019-10-12 18:25:18 +08:00
$cache = $container->get(\Psr\SimpleCache\CacheInterface::class);
2019-05-24 15:39:16 +08:00
```
2019-12-12 16:24:04 +08:00
### 註解方式
2019-03-22 17:41:09 +08:00
2019-12-12 16:24:04 +08:00
組件提供 `Hyperf\Cache\Annotation\Cacheable` 註解,作用於類方法,可以配置對應的緩存前綴、失效時間、監聽器和緩存組。
例如UserService 提供一個 user 方法,可以查詢對應 id 的用户信息。當加上 `Hyperf\Cache\Annotation\Cacheable` 註解後,會自動生成對應的 Redis 緩存key 值為 `user:id` ,超時時間為 `9000` 秒。首次查詢時,會從數據庫中查,後面查詢時,會從緩存中查。
2019-03-08 12:04:46 +08:00
2019-12-12 16:41:17 +08:00
> 緩存註解基於 [aop](zh-hk/aop.md) 和 [di](zh-hk/di.md),所以只有在 `Container` 中獲取到的對象實例才有效,比如通過 `$container->get` 和 `make` 方法所獲得的對象,直接 `new` 出來的對象無法使用。
2019-07-29 17:01:43 +08:00
2019-03-19 14:52:21 +08:00
```php
2019-03-08 12:04:46 +08:00
<?php
namespace App\Services;
use App\Models\User;
use Hyperf\Cache\Annotation\Cacheable;
class UserService
{
/**
* @Cacheable(prefix="user", ttl=9000, listener="user-update")
2019-03-08 12:04:46 +08:00
*/
public function user($id)
{
2019-04-05 10:01:15 +08:00
$user = User::query()->where('id',$id)->first();
2019-03-08 12:04:46 +08:00
if($user){
return $user->toArray();
}
return null;
}
}
2019-03-19 14:52:21 +08:00
```
2019-03-08 12:04:46 +08:00
2019-12-12 16:24:04 +08:00
### 清理 `@Cacheable` 生成的緩存
2019-03-08 12:04:46 +08:00
2019-12-12 16:24:04 +08:00
當然,如果我們數據庫中的數據改變了,如何刪除緩存呢?這裏就需要用到後面的監聽器。下面新建一個 Service 提供一方法,來幫我們處理緩存。
2019-03-08 12:04:46 +08:00
2019-03-19 14:52:21 +08:00
```php
2019-03-08 12:04:46 +08:00
<?php
declare(strict_types=1);
namespace App\Service;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Cache\Listener\DeleteListenerEvent;
use Psr\EventDispatcher\EventDispatcherInterface;
class SystemService
{
/**
* @Inject
* @var EventDispatcherInterface
*/
protected $dispatcher;
public function flushCache($userId)
{
$this->dispatcher->dispatch(new DeleteListenerEvent('user-update', [$userId]));
return true;
}
}
2019-03-22 17:41:09 +08:00
```
2019-12-12 16:24:04 +08:00
當我們自定義了 `Cacheable``value` 時,比如以下情況。
2019-11-26 17:19:36 +08:00
```php
<?php
declare(strict_types=1);
namespace App\Service\Cache;
use Hyperf\Cache\Annotation\Cacheable;
class DemoService
{
/**
* @Cacheable(prefix="cache", value="_#{id}", listener="user-update")
2019-11-26 17:19:36 +08:00
*/
public function getCache(int $id)
{
return $id . '_' . uniqid();
}
}
```
2019-12-12 16:24:04 +08:00
則需要對應修改 `DeleteListenerEvent` 構造函數中的 `$arguments` 變量,具體代碼如下。
2019-11-26 17:19:36 +08:00
```php
<?php
declare(strict_types=1);
namespace App\Service;
use Hyperf\Di\Annotation\Inject;
use Hyperf\Cache\Listener\DeleteListenerEvent;
use Psr\EventDispatcher\EventDispatcherInterface;
class SystemService
{
/**
* @Inject
* @var EventDispatcherInterface
*/
protected $dispatcher;
public function flushCache($userId)
{
$this->dispatcher->dispatch(new DeleteListenerEvent('user-update', ['id' => $userId]));
return true;
}
}
```
2019-12-12 16:24:04 +08:00
## 註解介紹
### Cacheable
2019-12-12 16:24:04 +08:00
例如以下配置,緩存前綴為 `user`, 超時時間為 `7200`, 刪除事件名為 `USER_CACHE`。生成對應緩存 KEY 為 `c:user:1`
```php
use App\Models\User;
use Hyperf\Cache\Annotation\Cacheable;
/**
* @Cacheable(prefix="user", ttl=7200, listener="USER_CACHE")
*/
public function user(int $id): array
{
$user = User::query()->find($id);
return [
'user' => $user->toArray(),
'uuid' => $this->unique(),
];
}
```
2019-12-12 16:24:04 +08:00
當設置 `value` 後,框架會根據設置的規則,進行緩存 `KEY` 鍵命名。如下實例,當 `$user->id = 1` 時,緩存 `KEY``c:userBook:_1`
```php
use App\Models\User;
use Hyperf\Cache\Annotation\Cacheable;
/**
* @Cacheable(prefix="userBook", ttl=6666, value="_#{user.id}")
*/
public function userBook(User $user): array
{
return [
'book' => $user->book->toArray(),
'uuid' => $this->unique(),
];
}
```
### CachePut
2019-12-12 16:24:04 +08:00
`CachePut` 不同於 `Cacheable`,它每次調用都會執行函數體,然後再對緩存進行重寫。所以當我們想更新緩存時,可以調用相關方法。
```php
use App\Models\User;
use Hyperf\Cache\Annotation\CachePut;
/**
* @CachePut(prefix="user", ttl=3601)
*/
public function updateUser(int $id)
{
$user = User::query()->find($id);
$user->name = 'HyperfDoc';
$user->save();
return [
'user' => $user->toArray(),
'uuid' => $this->unique(),
];
}
```
### CacheEvict
2019-12-12 16:24:04 +08:00
CacheEvict 更容易理解了,當執行方法體後,會主動清理緩存。
```php
use Hyperf\Cache\Annotation\CacheEvict;
/**
* @CacheEvict(prefix="userBook", value="_#{id}")
*/
public function updateUserBook(int $id)
{
return true;
}
```
2019-12-12 16:24:04 +08:00
## 緩存驅動
2019-07-24 10:07:56 +08:00
2019-12-12 16:24:04 +08:00
### Redis 驅動
2019-07-24 10:07:56 +08:00
2019-12-12 16:24:04 +08:00
`Hyperf\Cache\Driver\RedisDriver` 會把緩存數據存放到 `Redis` 中,需要用户配置相應的 `Redis 配置`。此方式為默認方式。
2019-07-24 10:07:56 +08:00
2019-12-12 16:24:04 +08:00
### 協程內存驅動
2019-07-24 10:07:56 +08:00
2019-12-12 16:24:04 +08:00
如果您需要將數據緩存到 `Context` 中,可以嘗試此驅動。例如以下應用場景 `Demo::get` 會在多個地方調用多次,但是又不想每次都到 `Redis` 中進行查詢。
2019-07-24 10:07:56 +08:00
```php
<?php
use Hyperf\Cache\Annotation\Cacheable;
class Demo {
public function get($userId, $id)
{
return $this->getArray($userId)[$id] ?? 0;
}
/**
* @Cacheable(prefix="test", group="co")
*/
2019-10-12 18:25:18 +08:00
public function getArray(int $userId): array
2019-07-24 10:07:56 +08:00
{
return $this->redis->hGetAll($userId);
}
}
```
2019-12-12 16:24:04 +08:00
對應配置如下:
2019-07-24 10:07:56 +08:00
```php
<?php
return [
'co' => [
'driver' => Hyperf\Cache\Driver\CoroutineMemoryDriver::class,
'packer' => Hyperf\Utils\Packer\PhpSerializerPacker::class,
],
];
```