<?php
/* * *********************************************************
 * [cml] (C)2012 - 3000 cml http://linhecheng.com
 * @Author  linhecheng<linhechengbush@live.com>
 * @Date: 13-6-26 上午11:23
 * @version  1.0 
 * cml框架 文件缓存驱动
 * *********************************************************** */

defined('CML_PATH') || exit();

import('CacheBase',CML_LIB_DRIVER_PATH.DIR_SEP.'Cache'.DIR_SEP, '.class.php');
class CacheFile extends CacheBase
{
	/**
	 * @var bool|array
	 */
	private $conf;

	public function __construct($conf = false)
	{
		$this->conf = $conf ? $conf : C('CACHE');
		$this->conf['CACHE_PATH'] = isset($this->conf['CACHE_PATH']) ? $this->conf['CACHE_PATH'] : RUNTIME_CACHE_PATH.DIR_SEP.'FileCache'.DIR_SEP;
		is_dir($this->conf['CACHE_PATH']) || mkdir($this->conf['CACHE_PATH'], 0700, true);
	}

	/**
	 * 获取缓存
	 *
	 * @param type string $key
	 *
	 * @return mixed
	 */
	public function get($key)
	{
		$fileName = $this->getFileName($key);
		if(!is_file($fileName)) return false;
		$data = file_get_contents($fileName);
		//缓存过期
		$fileTime = substr($data, 13, 10);
		$pos = strpos($data, ')');
		$cacheTime = substr($data, 24, $pos - 24);
		$data = substr($data, $pos + 1);
		if($cacheTime == 0) return unserialize ($data);

		if(time() > (intval($fileTime) + intval($cacheTime))) {
			unlink($fileName);
			return false;//缓存过期
		}
		return unserialize($data);            
	}

	/**
	 * 写入缓存
     	 *
	 * @param type string $key key
	 * @param type mixed $value 要缓存的数据
	 * @param type int $expire 缓存的过期时间 0为不过期
	 *
	 * @return bool
	 */

	public function set($key, $value, $expire = 0)
	{
		$fileName = $this->getFileName($key);
		if(file_put_contents($fileName, '<?php exit;?>'.time()."($expire)".serialize($value))) {
			clearstatcache();
			return true;
		} else{
			return false;
		}

	}

	/**
	 * 更新缓存  可以直接用set但是为了一致性操作所以做此兼容
	 *
	 * @param type string $key
	 * @param type mixed $value
	 * @param type int $expire
	 *
	 * @return bool
	 */
	public function update($key, $value, $expire = 0)
	{
		return $this->set($key, $value, $expire);
	}

	/**
	 * 删除缓存
	 *
	 * @param type string $key
	 *
	 * @return bool
	 */
	public function delete($key)
	{
		$fileName = $this->getFileName($key);      
		return unlink($fileName);
	}

	/**
	 * 清空缓存
	 *
	 * @return bool
	 */
	public function truncate()
	{
		@set_time_limit(60);
		if(!is_dir($this->conf['CACHE_PATH'])) return true;
		$path = opendir($this->conf['CACHE_PATH']);
		while (false !== ($fileName = readdir($path))) {
			if ($fileName !== '.' && $fileName !== '..') {
				@unlink($this->conf['CACHE_PATH'] .DIR_SEP.$fileName);
			}
		}
		closedir($path);
		return true;
	}

	/**
	 * 自增
	 *
	 * @param $key
	 * @param int $val
	 *
	 * @return bool
	 */
	public function increment($key, $val = 1)
	{
		$v = $this->get($key);
		if(is_int($v)) {
			return $this->update($key,  $v - intval($val));
		} else {
			return false;
		}
	}

	/**
	 * 自减
	 *
	 * @param $key
	 * @param int $val
	 *
	 * @return bool
	 */
	public function decrement($key, $val = 1)
	{
		$v = $this->get($key);
		if(is_int($v)) {
			return $this->update($key,  $v - intval($val));
		} else {
			return false;
		}
	}

	/**
	 * 获取缓存文件名
	 *
	 * @param  string $key 缓存名
	 *
	 * @return string
	 */
	private function getFileName($key)
	{
		return $this->conf['CACHE_PATH'] . md5($this->conf['PREFIX'] . $key) . '.php';
	}

}