1、编辑缓存的控制器类,/api/controllers/CacheController.php
<?php
namespace api/controllers;
use yii/rest/ActiveController;
/**
* Class CacheController
* @package api/controllers
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class CacheController extends ActiveController
{
public $serializer = [
'class' => 'api/rests/cache/Serializer',
'collectionEnvelope' => 'items',
];
/**
* @inheritdoc
*/
public function actions()
{
$actions = parent::actions();
// 禁用"view"、"create"、"update"、"options"动作
unset($actions['view'], $actions['create'], $actions['update'], $actions['options']);
$actions['index']['class'] = 'api/rests/cache/IndexAction';
$actions['delete']['class'] = 'api/rests/cache/DeleteAction';
$actions['flush'] = [
'class' => 'api/rests/cache/FlushAction',
'modelClass' => $this->modelClass,
'checkAccess' => [$this, 'checkAccess'],
];
return $actions;
}
}
2、创建缓存的资源类的数据层(相应的模型语言包文件),/common/models/redis/Cache.php
<?php
namespace common/models/redis;
use Yii;
use common/components/redis/ActiveRecord;
/**
* This is the model class for table "{{%cache}}".
*
* @property int $id
* @property string $cache_component_name 组件ID
* @property string $key 缓存键
* @property string $value 缓存值
*/
class Cache extends ActiveRecord
{
/**
* @return array the list of attributes for this record
*/
public function attributes()
{
return ['id', 'cache_component_name', 'key', 'value'];
}
/**
* @inheritdoc
*/
public function rules()
{
return [
[['id', 'cache_component_name', 'key', 'value'], 'safe'],
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'id' => Yii::t('model/redis/cache', 'ID'),
'cache_component_name' => Yii::t('model/redis/cache', 'Cache Component Name'),
'key' => Yii::t('model/redis/cache', 'Key'),
'value' => Yii::t('model/redis/cache', 'Value'),
];
}
}
3、创建缓存的资源类的逻辑层,/common/logics/redis/Cache.php
<?php
namespace common/logics/redis;
use Yii;
use common/logics/redis/CacheComponent as RedisCacheComponent;
use yii/web/NotFoundHttpException;
class Cache extends /common/models/redis/Cache
{
/**
* 返回缓存组件下的所有key(拼接规则),键是缓存组件名,值是键名列表
* @param string $cacheComponentName 组件ID
* @return array|false
*
* 格式如下:
*
* 缓存组件下的所有key
* [
* 'tenantKey' => [
* 'key' => 'tenantKey'
* 'value' => 'tenant:{tenantid}'
* ]
* 'idaKey' => [
* 'key' => 'idaKey'
* 'value' => 'tenant:{tenantid}:ida:{uid}'
* ]
* ]
*
* 失败
* false
*/
function getCacheKeys($cacheComponentName)
{
$redisCacheComponent = new RedisCacheComponent();
$cacheComponents = $redisCacheComponent->getCacheComponents([$cacheComponentName]);
if (empty($cacheComponents)) {
return false;
}
$cacheKeys = [];
if (isset(Yii::$app->params['cache'][$cacheComponentName])) {
foreach (Yii::$app->params['cache'][$cacheComponentName]['keys'] as $k => $v) {
$cacheKeys[$k] = ['key' => $k, 'value' => $v];
}
}
return $cacheKeys;
}
/**
* @param $id
* @return /yii/caching/Cache|null
* @throws HttpException
* @throws /yii/base/InvalidConfigException
*/
public static function getCacheComponent($id)
{
$redisCacheComponent = new RedisCacheComponent();
$cacheComponents = $redisCacheComponent->getCacheComponents();
if (!in_array($id, array_keys($cacheComponents))) {
throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '20015'), ['id' => $id])), 20015);
}
return Yii::$app->get($id);
}
}
4、在接口应用中,创建缓存的资源类,/api/models/redis/Cache.php
<?php
namespace api/models/redis;
class Cache extends /common/logics/redis/Cache
{
}
5、在接口应用的v1模块中,创建缓存的资源类,/api/modules/v1/models/redis/Cache.php
<?php
namespace api/modules/v1/models/redis;
class Cache extends /api/models/redis/Cache
{
}
6、在接口应用的v1模块中,创建缓存的控制器类,定义模型类,/api/modules/v1/controllers/CacheController.php
<?php
namespace api/modules/v1/controllers;
/**
* Cache controller for the `v1` module
*/
class CacheController extends /api/controllers/CacheController
{
public $modelClass = 'api/modules/v1/models/redis/Cache';
}
7、创建参数配置文件,获取某缓存组件下的所有key,缓存 API 不支持,因此决定基于配置返回所有key的拼接规则,/common/config/params.php
<?php
return [
'adminEmail' => env('ADMIN_EMAIL'),
'robotEmail' => env('ROBOT_EMAIL'),
'availableLocales'=>[
'en-US'=>'English (US)',
'ru-RU'=>'Русский (РФ)',
'uk-UA'=>'Українська (Україна)',
'es' => 'Español',
'vi' => 'Tiếng Việt',
'zh-CN' => '简体中文',
'pl-PL' => 'Polski (PL)',
],
'cache' => [
'redisCache' => [
'keys' => [
'tenantKey' => 'tenant:{tenantid}', //多租户数据的缓存键
'idaKey' => 'tenant:{tenantid}:ida:{uid}', //权限中心数据的缓存键
],
],
],
];
8、编辑 /common/config/base.php,引入参数配置文件,如图1
9、创建获取缓存列表的方法类(获取某缓存组件下的所有key),/api/rests/cache/IndexAction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api/rests/cache;
use Yii;
use yii/data/ArrayDataProvider;
use yii/web/NotFoundHttpException;
/**
* IndexAction implements the API endpoint for listing multiple models.
*
* For more details and usage information on IndexAction, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class IndexAction extends /yii/rest/IndexAction
{
/**
* Prepares the data provider that should return the requested collection of the models.
* @return ActiveDataProvider
*/
protected function prepareDataProvider()
{
$requestParams = Yii::$app->getRequest()->getBodyParams();
if (empty($requestParams)) {
$requestParams = Yii::$app->getRequest()->getQueryParams();
}
$filter = null;
if ($this->dataFilter !== null) {
$this->dataFilter = Yii::createObject($this->dataFilter);
if ($this->dataFilter->load($requestParams)) {
$filter = $this->dataFilter->build();
if ($filter === false) {
return $this->dataFilter;
}
}
}
if ($this->prepareDataProvider !== null) {
return call_user_func($this->prepareDataProvider, $this, $filter);
}
/* @var $modelClass /yii/db/BaseActiveRecord */
$modelClass = $this->modelClass;
$model = new $modelClass();
if (empty($requestParams['cache_component_name'])) {
return ['code' => 20014, 'message' => Yii::t('error', '20014')];
}
$allModels = $model->getCacheKeys($requestParams['cache_component_name']);
if ($allModels === false) {
throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '20015'), ['id' => $requestParams['cache_component_name']])), 20015);
}
return Yii::createObject([
'class' => ArrayDataProvider::className(),
'allModels' => $allModels,
'pagination' => [
'params' => $requestParams,
],
'sort' => [
'params' => $requestParams,
],
]);
}
}
10、创建获取缓存列表的数据序列化类,/api/rests/cache/Serializer.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api/rests/cache;
use Yii;
use yii/data/DataProviderInterface;
/**
* Serializer converts resource objects and collections into array representation.
*
* Serializer is mainly used by REST controllers to convert different objects into array representation
* so that they can be further turned into different formats, such as JSON, XML, by response formatters.
*
* The default implementation handles resources as [[Model]] objects and collections as objects
* implementing [[DataProviderInterface]]. You may override [[serialize()]] to handle more types.
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class Serializer extends /yii/rest/Serializer
{
/**
* Serializes a data provider.
* @param DataProviderInterface $dataProvider
* @return array the array representation of the data provider.
*/
protected function serializeDataProvider($dataProvider)
{
if ($this->preserveKeys) {
$models = $dataProvider->getModels();
} else {
$models = array_values($dataProvider->getModels());
}
$models = $this->serializeModels($models);
if (($pagination = $dataProvider->getPagination()) !== false) {
$this->addPaginationHeaders($pagination);
}
if ($this->request->getIsHead()) {
return null;
} elseif ($this->collectionEnvelope === null) {
return $models;
}
$result = [
$this->collectionEnvelope => $models,
];
if (empty($result['items'])) {
return ['code' => 20016, 'message' => Yii::t('error', '20016')];
}
if ($pagination !== false) {
return ['code' => 10000, 'message' => Yii::t('app', '10008'), 'data' => array_merge($result, $this->serializePagination($pagination))];
}
return ['code' => 10000, 'message' => Yii::t('app', '10008'), 'data' => $result];
}
}
11、新增获取缓存列表的路由配置,编辑 /api/config/_urlManager.php
[
'class' => 'yii/rest/UrlRule',
'controller' => ['v1/cache'],
'only' => ['index', 'delete', 'flush'],
'extraPatterns' => [
'DELETE flush/{id}' => 'flush',
],
],
12、GET http://www.cmcp-api.localhost/v1/caches?tenantid=default&api_gateway_user_id=1&cache_component_name=redisCache ,响应成功
{
"code": 10000,
"message": "获取缓存列表成功",
"data": {
"items": [
{
"key": "tenantKey",
"value": "tenant:{tenantid}"
},
{
"key": "idaKey",
"value": "tenant:{tenantid}:ida:{uid}"
}
],
"_links": {
"self": {
"href": "http://www.cmcp-api.localhost/v1/caches?tenantid=default&api_gateway_user_id=1&cache_component_name=redisCache&page=1"
}
},
"_meta": {
"totalCount": 2,
"pageCount": 1,
"currentPage": 1,
"perPage": 20
}
}
}
13、DELETE http://www.cmcp-api.localhost/v1/caches/tenant:default?tenantid=default&api_gateway_user_id=1 ,响应404,如图2
{
"name": "Not Found",
"message": "页面未找到。",
"code": 0,
"status": 404,
"type": "yii//web//NotFoundHttpException"
}
14、编辑获取缓存列表的路由配置,编辑 /api/config/_urlManager.php,配置正则,表示允许{id}的值为任意一个字母、数字、下划线、逗号、冒号所组成的字符串(逗号、冒号不能够做为开头字符)
[
'class' => 'yii/rest/UrlRule',
'controller' => ['v1/cache'],
'only' => ['index', 'delete', 'flush'],
'extraPatterns' => [
'DELETE flush/{id}' => 'flush',
],
'tokens' => ['{id}' => '<id://w[//w,:]*>'],
],
15、创建Action类,其是实现RESTful API的动作类的基类,/api/rests/cache/Action.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api/rests/cache;
use Yii;
use yii/db/ActiveRecordInterface;
use yii/web/NotFoundHttpException;
/**
* Action is the base class for action classes that implement RESTful API.
*
* For more details and usage information on Action, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class Action extends /yii/rest/Action
{
/**
* Returns the data model based on the primary key given.
* If the data model is not found, a 404 HTTP exception will be raised.
* @param string $id the ID of the model to be loaded. If the model has a composite primary key,
* the ID must be a string of the primary key values separated by commas.
* The order of the primary key values should follow that returned by the `primaryKey()` method
* of the model.
* @return ActiveRecordInterface the model found
* @throws NotFoundHttpException if the model cannot be found
*/
public function findModel($id)
{
$requestParams = Yii::$app->getRequest()->getBodyParams();
if (empty($requestParams)) {
$requestParams = Yii::$app->getRequest()->getQueryParams();
}
if ($this->findModel !== null) {
return call_user_func($this->findModel, $id, $this);
}
/* @var $modelClass ActiveRecordInterface */
$modelClass = $this->modelClass;
if ($id !== null) {
$model = $modelClass::getCacheComponent($id);
}
if (isset($model)) {
return $model;
}
throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '20015'), ['id' => $id])), 20015);
}
}
16、创建删除缓存的方法类(基于缓存组件ID + 缓存键),/api/rests/cache/DeleteAction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api/rests/cache;
use Yii;
use yii/web/NotFoundHttpException;
use yii/web/ServerErrorHttpException;
/**
* DeleteAction implements the API endpoint for deleting a model.
*
* For more details and usage information on DeleteAction, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class DeleteAction extends Action
{
/**
* Deletes a model.
* @param mixed $id id of the model to be deleted.
* @throws ServerErrorHttpException on failure.
*/
public function run($id)
{
$requestParams = Yii::$app->getRequest()->getBodyParams();
if (empty($requestParams)) {
$requestParams = Yii::$app->getRequest()->getQueryParams();
}
if (empty($requestParams['cache_component_name'])) {
return ['code' => 20014, 'message' => Yii::t('error', '20014')];
}
$model = $this->findModel($requestParams['cache_component_name']);
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id, $model);
}
if ($model->get($id) === false) {
throw new NotFoundHttpException(Yii::t('error', Yii::t('error', Yii::t('error', '20017'), ['key' => $id])), 20017);
}
if ($model->delete($id) === false) {
throw new ServerErrorHttpException('Failed to delete the object for unknown reason.');
}
return ['code' => 10000, 'message' => Yii::t('app', '10009')];
}
}
17、删除缓存,DELETE http://www.cmcp-api.localhost/v1/caches/tenant:default?tenantid=default&api_gateway_user_id=1&cache_component_name=redisCache ,响应200,如图3
18、创建清空缓存,即删除某个缓存组件ID中的所有数据的方法类,/api/rests/cache/FlushAction.php
<?php
/**
* @link http://www.yiiframework.com/
* @copyright Copyright (c) 2008 Yii Software LLC
* @license http://www.yiiframework.com/license/
*/
namespace api/rests/cache;
use Yii;
use yii/web/NotFoundHttpException;
use yii/web/ServerErrorHttpException;
/**
* DeleteAction implements the API endpoint for deleting a model.
*
* For more details and usage information on DeleteAction, see the [guide article on rest controllers](guide:rest-controllers).
*
* @author Qiang Wang <shuijingwanwq@163.com>
* @since 1.0
*/
class FlushAction extends Action
{
/**
* Deletes a model.
* @param mixed $id id of the model to be deleted.
* @throws ServerErrorHttpException on failure.
*/
public function run($id)
{
$model = $this->findModel($id);
if ($this->checkAccess) {
call_user_func($this->checkAccess, $this->id, $model);
}
if ($model->flush() === false) {
throw new ServerErrorHttpException('Failed to delete the object for unknown reason.');
}
return ['code' => 10000, 'message' => Yii::t('app', '10010')];
}
}
19、查看Redis,包含Redis cache、Redis 活动记录等数据,如图4
20、清空缓存,DELETE http://www.cmcp-api.localhost/v1/caches/flush/redisCache?tenantid=default&api_gateway_user_id=1 ,响应200,如图5
21、查看Redis,发现不仅是Redis cache被全部删除了,且Redis 活动记录等数据也被全部删除了,得出结论:redisCache组件中flush()操作,删除Redis中的所有数据,如图6
原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/webdev/180975.html
