php使用装饰模式无侵入式加缓存

<?php


namespace App\Services;

use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redis;

class CacheDecorator
{
    // 公司组织列表缓存key
    const COMPANY_ORGANIZE_KEY = 'company_organize_%s';

    private static function setStringCacheStorage($key, $expireTime, string $data)
    {
        if ($expireTime) {
            Redis::setex($key, $expireTime, $data);
        } else {
            Redis::set($key, $data);
        }
    }


    /**
     * 装饰器获取缓存数据
     * @param $cacheKey 缓存key
     * @param int $cacheTime 缓存时间
     * @param object $obj 对象
     * @param $method 缓存方法
     * @param mixed ...$args 参数
     * @return mixed
     */
    public static function getStringCache($cacheKey, $expireTime, object $obj, $method, ...$args)
    {
        try {
            $cacheData = Redis::get($cacheKey);
            $cacheData = json_decode($cacheData, true);
            if (empty($cacheData) || !isset($cacheData['org_data']) || empty($cacheData['org_data'])) {
                $cacheData = [
                    'org_data' => call_user_func_array([$obj, $method], $args)
                ];
                self::setStringCacheStorage($cacheKey, $expireTime, json_encode($cacheData, JSON_UNESCAPED_UNICODE));
                Log::info('从数据库获取数据', [
                    'class'  => get_class($obj),
                    'method' => $method,
                    'args'   => $args,
                ]);
                return $cacheData['org_data'];
            } else {
                Log::info('从缓存获取数据', [
                    'class'  => get_class($obj),
                    'method' => $method,
                    'args'   => $args,
                ]);
                return $cacheData['org_data'];
            }
        } catch (\Exception $e) {
            Log::error("redis缓存错误", [
                'msg'  => $e->getMessage(),
                'line' => $e->getLine(),
                'file' => $e->getFile(),
            ]);
        }
        Log::info('从数据库获取数据', [
            'class'  => get_class($obj),
            'method' => $method,
            'args'   => $args,
        ]);
        return call_user_func_array([$obj, $method], $args);
    }

    /**
     * 获取缓存key
     * @param $format
     * @param mixed ...$arg
     * @return string
     */
    public static function getCacheKey($format, ...$arg)
    {
        return sprintf($format, ...$arg);
    }
}

调用

   public function listOrganize(AuthOrganizeService $authOrganizeService)
    {
        // before直接调用数据库
        $list = $authOrganizeService->listCompanyOrganize(Auth::user()->company_id);
        // after 直接使用缓存,但是listCompanyOrganize这个方法是没有进行任何的改动
        $list = CacheDecorator::getStringCache(
            CacheDecorator::getCacheKey(CacheDecorator::COMPANY_ORGANIZE_KEY),
            100,
            AuthOrganizeService,
            'listCompanyOrganize',
            1
        );
        $res  = [
            'list'  => $list,
            'total' => 1    //不分页
        ];
        return $this->success($res);
    }

 

posted @ 2019-12-10 19:59  Sentiger  阅读(254)  评论(1编辑  收藏  举报