在 Yii 2 Starter Kit 中实现 RESTful 应用的删除缓存(获取缓存列表(基于缓存组件ID)、删除缓存(基于缓存组件ID + 缓存键)、清空缓存,即删除某个缓存组件ID中的所有数据)

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

编辑 /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"
}
DELETE http://www.cmcp-api.localhost/v1/caches/tenant:default?tenantid=default&api_gateway_user_id=1 ,响应404

图2

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

删除缓存,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

查看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

清空缓存,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

查看Redis,发现不仅是Redis cache被全部删除了,且Redis 活动记录等数据也被全部删除了,得出结论:redisCache组件中flush()操作,删除Redis中的所有数据

图6

 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/180975.html

(0)
上一篇 2021年10月31日
下一篇 2021年10月31日

相关推荐

发表回复

登录后才能评论