<?php
/**
 * 文件缓存
 * @copyright reginx.com
 * $Id: file.cache.php 60 2013-02-06 09:43:35Z reginx $
 */
class file_cache{

    /**
     * 配置信息
     *
     * @var unknown_type
     */
    private $_dir = array();
    
    private $_pre  = 'pre_';

    /**
     * 架构函数
     *
     * @param unknown_type $conf
     */
    public function __construct($conf = array()){
        $this->_pre = isset($conf['pre']) ? $conf['pre'] : 'pre_';
        $this->_dir = isset($conf['dir']) ? $conf['dir'] : $GLOBALS['_APP']['cache_path'];
    }

    /**
     * 设置缓存
     *
     * @param String $key
     * @param Mixed $val
     * @param Integer $ttl
     * @return Mixed
     */
    function set($key, $val, $ttl = 0){
        cache_extra::count(0);
        $key  = $this->_pre . $key;
        $file = $this->getcachefile($key);
        $data = "<?php\r\n/**\r\n *  @Created By Reginx v" . REGINX_VERSION . " FileCache\r\n *  @Time:" . date('Y-m-d H:i:s', REQUEST_TIME) . "\r\n */";
        $data .= $this->getexpstr(intval($ttl));
        $data .= "\r\nreturn " . var_export($val, true) . ";\r\n?>";
        return file_put_contents($file, $data, LOCK_EX);
    }

    /**
     * 获取缓存内容
     *
     * @param String $key
     * @return Mixed
     */
    function get($key){
        cache_extra::count(1);
        $key  = $this->_pre . $key;
        $file = $this->getcachefile($key);
        if(!is_file($file)){
            return false;
        }
        $data = include ($file);
        return $data;
    }

    /**
     * 删除单个缓存
     *
     * @param unknown_type $key
     */
    function delete($key){
        $key  = $this->_pre . $key;
        $file = $this->getcachefile($key);
        if(is_file($file)){
            unlink($file);
        }
    }

    /**
     * 清除所有缓存
     */
    function clear($key = NULL){
        if(empty($key)){
            core::removeDir($this->_dir, 1);
        }else{
            core::removeDir($this->_dir . $this->getdir($this->_pre . $key), 1);
        }
    }

    /**
     * 获取过期条件字串
     *
     * @param Integer $ttl
     * @return String
     */
    public function getexpstr($ttl = 0){
        if($ttl < 1){
            return '';
        }
        return "\r\n\r\n" . 'if(' . (REQUEST_TIME + $ttl) . ' < REQUEST_TIME) return false;' . "\r\n";
    }

    /**
     * 获取缓存文件
     *
     * @param String $key
     * @return String
     */
    public function getcachefile($key){
        $dir = $this->getdir($key);
        core::makeDir($this->_dir . $dir);
        return $this->_dir . $dir . '/' . $this->getfilename($key);
    }

    /**
     * 获取Key对应的散列值作为文件名
     *
     * @param String $key
     * @return Integer
     */
    public function getfilename($key){
        return sprintf('%X', crc32($key)) . '.php';
    }

    /**
     * 获取目录
     *
     * @param unknown_type $key
     * @return unknown
     */
    function getdir($key){
        return sprintf('%08X', abs(crc32(substr($key, 0, strpos($key, '@')))));
    }
    

    /**
     * 运行状态统计
     */
    public function stat(){
        $ret   = $stat  = array();
        $stat  = $this->get('filecachestat');
        if(empty($stat)){
            self::getfilestat(null , $stat);
            // 十分钟更新一次
            $this->set('filecachestat' , $stat , 600);
        }
        $ret[] = array('缓存目录' , realpath(CACHE_PATH));
        $ret[] = array('文件个数' , $stat['nums']);
        $ret[] = array('缓存总量' , sprintf('%.2f K' , $stat['total']  / 1024));
        return $ret;
    }
    
    
    
    public static function getfilestat($path = null , &$ret){
        if(empty($ret)){
            $ret = array('nums' => 0, 'total' => 0);
        }
        if(empty($path)){
            $path = CACHE_PATH . '*';
        }else{
            $path = realpath($path) . '/*';
        }
        foreach (glob($path) as $v){
            if(is_file($v)){
                $ret['nums']++;
                $ret['total'] += filesize($v);
            }else{
                self::getfilestat($v , $ret);
            }
        }
    }
}
?>