params['redis'], Yii::$app->params['redis']['livetime']) ? (int) Yii::$app->params['redis']['livetime'] : 300; } return self::$livetime; } protected static function prefix() { if (!self::$prefix) { self::$prefix = isset(Yii::$app->params['redis'], Yii::$app->params['redis']['prefix']) ? (int) Yii::$app->params['redis']['prefix'] : ''; } return self::$prefix; } protected static function calculateKey($key) { return self::prefix() . $key; } public static function hdel($key, $value) { if (self::$setDeleteKey) { self::addDeleteKey($key, $value); } else { Yii::$app->redis->hdel(self::calculateKey($key), $value); } } public static function del($key, $realDelete = false) { if (self::$setDeleteKey && !$realDelete) { self::addDeleteKey($key); } else { Yii::$app->redis->del(self::calculateKey($key)); } } public static function hset($key, $field, $value) { return self::getActive() ? Yii::$app->redis->hset(self::calculateKey($key), $field, $value) : false; } public static function hsetModel($key, $field, $model) { return self::hset($key, $field, is_object($model) ? $model->attributes : null); } /** * * @param type $key * @param type $field * @param type $modelArray * @param type $page родительская модель (используется для пагинации) * @return type */ public static function hsetModelArray($key, $field, $modelArray, $page = null) { $values = []; foreach ($modelArray as $model) { $values[] = $model->attributes; } if ($page) { $values['page'] = [ 'totalCount' => $page->totalCount, 'perPage' => $page->perPage, 'sort' => $page->sort, ]; $field .= ":page:{$page->page}:perPage:{$page->perPage}:sort:{$page->sort}"; } return self::hset($key, $field, $values); } public static function hget($key, $field) { return self::getActive() ? Yii::$app->redis->hget(self::calculateKey($key), $field) : false; } public static function hgetModel($key, $field, $className) { $value = self::hget($key, $field); return empty($value) ? $value : (new $className($value)); } public static function hgetModelArray($key, $field, $className, $page = null) { if ($page) { $field .= ":page:{$page->page}:perPage:{$page->perPage}:sort:{$page->sort}"; } $values = self::hget($key, $field); if ($values === false) { return false; } $ids = []; foreach ($values as $keyVal => $value) { if ($keyVal !== 'page' && isset($value['id'])) { $ids[] = $value['id']; } } $output = []; foreach ($values as $keyVal => $value) { if ($keyVal === 'page') { if ($page) { $page->setMeta($value['totalCount'], $value['perPage']); $page->sort = $value['sort']; } } else { $model = new $className($value); if (isset($model->ids)) { $model->ids = $ids; } $output[] = $model; } } return $output; } public static function delete($key, array $patterns) { if (self::getActive()) { foreach ($patterns as $pattern) { $cursor = NULL; foreach ($patterns as $pattern) { $arKeys = []; while ($values = Yii::$app->redis->hscan(self::calculateKey($key), $cursor, $pattern)) { foreach ($values as $vkey => $value) { $arKeys[] = $vkey; } } foreach ($arKeys as $value) { self::hdel($key, $value); } } } } } /** * удаление одного элемента * @param type $key * @return type */ public static function deleteAll($key, $realDelete = false) { if (self::getActive()) { self::del($key, $realDelete); } } public static function getKeyTypes() { $result = Yii::$app->redis->keys(self::calculateKey('*')); $output = ['*']; foreach ($result as $val) { $arVal = explode(':', $val); if (isset($arVal[1]) && !in_array($arVal[1], $output)) { $output[] = $arVal[1]; } } sort($output); return $output; } /** * Удаление всех элементов по шаблоку * @param type $type * @return boolean */ public static function deleteType($type) { if (self::getActive()) { self::deleteAll($type); $type = $type == "*" ? "*" : "{$type}:*"; $result = Yii::$app->redis->keys(self::calculateKey($type)); foreach ($result as $val) { self::deleteAll(str_replace(self::prefix(), '', $val)); } } return true; } public static function set($key, $value, $options = null) { $result = false; if (self::getActive()) { if ($options === true) { $options = ['EX' => self::livetime()]; } elseif (is_int($options)) { $options = ['EX' => $options]; } $json = json_encode($value); Yii::$app->redis->set(self::calculateKey($key), $json, $options); } return $result; } public static function setModel($key, $model, $options = true) { return self::set($key, is_object($model) ? $model->attributes : null, $options); } public static function setModelArray($key, $modelArray, $page = null, $options = true) { $values = []; foreach ($modelArray as $model) { $values[] = $model->attributes; } if ($page) { $values['page'] = [ 'totalCount' => $page->totalCount, 'perPage' => $page->perPage, 'sort' => $page->sort, ]; } return self::set($key, $values, $options); } public static function get(string $key) { $result = false; if (self::getActive()) { $result = Yii::$app->redis->get(self::calculateKey($key)); } return $result ? json_decode($result, true) : $result; } public static function getModel($key, $className) { $value = self::get($key); return empty($value) ? $value : (new $className($value)); } public static function getModelArray($key, $className, $page = null) { $values = self::get($key); if ($values === false) { return false; } $ids = []; foreach ($values as $keyVal => $value) { if ($keyVal !== 'page' && isset($value['id'])) { $ids[] = $value['id']; } } $output = []; foreach ($values as $keyVal => $value) { if ($keyVal === 'page') { if ($page) { $page->setMeta($value['totalCount'], $value['perPage']); $page->sort = $value['sort']; } } else { $model = new $className($value); if (isset($model->ids)) { $model->ids = $ids; } $output[] = $model; } } return $output; } /** * Доюавляем в лист удаляемый индекс * @param type $key * @param type $field * @return type */ public static function addDeleteKey($key, $field = '-') { return self::hset('del:' . $key, $field, time() + self::$keysDeleteTime); } /** * Удаляет устаревший кеш * @return type */ public static function oldCacheDelete() { $result = Yii::$app->redis->keys(self::calculateKey('del:*')); foreach ($result as $val) { $cursor = null; $key = str_replace(self::prefix(), '', $val); $pattern = '*'; $arKeys = []; while ($values = Yii::$app->redis->hscan(self::calculateKey($key), $cursor, $pattern)) { foreach ($values as $vkey => $value) { if ($value < time()) { $arKeys[] = $vkey; } } } $keyCache = str_replace(self::prefix() . "del:", '', $val); foreach ($arKeys as $value) { self::$setDeleteKey = false; if ($value == '-') { self::del($keyCache); } else { self::hdel($keyCache, $value); } self::hdel($key, $value); } } } }