Parser.php 2.87 KB
<?php

namespace common\components\cachekey;

use Yii;

/**
 * @author wuxiao
 * @date 2016-8-29
 */
class Parser{
    
    /**
     * 缓存句柄
     * @var type 
     */
    private $cache;
    
    /**
     * 缓存过期时间,秒
     * @var type 
     */
    private $expire = 0;
    
    /**
     * 错误信息
     * @var type 
     */
    static $error;
    
    static function self(){
        static $self;
        if (empty($self)){
            $self = new self;
        }
        return $self;
    }
    
    public function __construct() {
        $this->cache = Yii::createObject('yii\caching\ArrayCache');
    }
    
    static function get($path,$params){
        $self = self::self();
        
        $main_key = 'get'.$path.serialize($params);
        if ($realkey = $self->cache->get($main_key)){
            return $realkey;
        }
        
        $key = 'cacheKey'.$path;
        if (!$cachekey = $self->cache->get($key)){
            $cache = basename($path);
            $dir = dirname($path);
            if (!$cacheMap = $self->read($dir)){
                self::$error = 'cannot read '.$path;
                return;
            }
            if (empty($cacheMap[$cache])){
                self::$error = 'cannot find map key '.$cache;
                return;
            }
            $cachekey = $cacheMap[$cache];
            $self->cache->set($key,$cachekey,$self->expire);
        }        
        
        if (func_num_args() > 2){
            $params = func_get_args();
            array_shift($params);
        }
        if (is_array($params)){
            if (!is_list($params)){
                $dict = $list = [];
                foreach ($params as $tag=>$value){
                    if (!is_int($tag)){
                        $dict['{'.$tag.'}'] = $value;
                    }else{
                        $list[] = $value;
                    }
                }
                $cachekey = strtr($cachekey,$dict);
                $params = $list;
            }
            
            $realkey = preg_replace('/{[^}]+}/', '%s', $cachekey);
            $realkey = call_user_func_array('sprintf',array($realkey)+$params);
        }else{
            $realkey = preg_replace('/{[^}]+}/', '%s', $cachekey);
            $realkey = sprintf($realkey,$params);
        }
        
        $self->cache->set($main_key,$realkey,$self->expire);
        return $realkey;
    }
    
    private function read($path){
        $key = __FUNCTION__.$path;
        if (!$content = $this->cache->get($key)){
            if (!is_readable($file = __DIR__.'/keys/'.$path.'.php')){
                return false;
            }
            $content = include($file);
            $this->cache->set($key,$content,$this->expire);
        }
        return $content;
    }
}
if (!function_exists('is_list')){
    function is_list(array $arr){
        return array_keys($arr) === range(0,count($arr)-1);
    }
}