PHP文件缓存示例
简介
在php程序中,缓存可以存储到Redis或者Memcache中,如果没有这些条件,或者服务器内存非常有限怎么办?可以将缓存内容写入到硬盘,写入到文件系统中,也是一个思路。下面是示例代码:
代码
<?php
namespace common\library;
use Psr\SimpleCache\CacheInterface;
class FileCache implements CacheInterface
{
protected $filename;
protected $handle;
protected $keys = [];
protected $spaceSize;
protected $startTimestamp;
public function __construct($filename, $spaceSize = 1024)
{
$this->startTimestamp = time();
$this->filename = $filename;
$this->spaceSize = $spaceSize;
!is_dir(dirname($this->filename)) && mkdir(dirname($this->filename), 0755, true);
$this->handle = fopen($this->filename, 'w+');
}
public function __destruct()
{
fclose($this->handle);
unlink($this->filename);
}
public function get($key, $default = null)
{
$key = substr(md5($key), 0, 20);
if (!isset($this->keys[$key])) {
return $default;
}
$item = $this->parseId($this->keys[$key]);
if ($item[1] != 0 && (time() - $this->startTimestamp) > $item[1]) {
return $default;
}
fseek($this->handle, $item[0] * $this->spaceSize);
$value = fread($this->handle, $this->spaceSize);
return unserialize(rtrim($value));
}
public function set($key, $value, $ttl = null)
{
$key = substr(md5($key), 0, 20);
$value = serialize($value);
if (strlen($value) > $this->spaceSize - 1) {
throw new \RuntimeException('not enough space');
}
if (!is_null($ttl) && $ttl > 1048575) {
throw new \RuntimeException('Ttl out of range');
}
$value = str_pad($value, $this->spaceSize - 1, " ") . "\n";
if (isset($this->keys[$key])) {
$item = $this->parseId($this->keys[$key]);
$start = $item[0] * $this->spaceSize;
$index = $item[0];
} else {
$count = count($this->keys);
$start = $count * $this->spaceSize;
$index = $count;
}
fseek($this->handle, $start, SEEK_SET);
fwrite($this->handle, $value);
fflush($this->handle);
$this->keys[$key] = $this->getId($ttl ? (time() - $this->startTimestamp) + $ttl : 0, $index);
return true;
}
public function delete($key)
{
$key = substr(md5($key), 0, 20);
unset($this->keys[$key]);
return true;
}
public function clear()
{
ftruncate($this->handle, 0);
fflush($this->handle);
return true;
}
public function getMultiple($keys, $default = null)
{
$values = [];
foreach ($keys as $key) {
$values[$key] = $this->get($key, $default);
}
return $values;
}
public function setMultiple($values, $ttl = null)
{
foreach ($values as $key => $value) {
$this->set($key, $value, $ttl);
}
return true;
}
public function deleteMultiple($keys)
{
foreach ($keys as $key) {
$this->delete($key);
}
return true;
}
public function has($key)
{
return isset($this->keys[md5($key)]);
}
protected function getId($time, $count)
{
return $time << 20 | $count;
}
protected function parseId($id)
{
$id = str_pad(decbin($id), 40, '0', STR_PAD_LEFT);
return [bindec(substr($id, 21)), bindec(substr($id, 0, 20))];
}
}