File.php 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace Lib\StoreDriver;
  3. /**
  4. *
  5. * 这里用php数组文件来存储数据,
  6. * 为了获取高性能需要用类似memcache的存储
  7. * @author walkor <workerman.net>
  8. *
  9. */
  10. class File
  11. {
  12. // 为了避免频繁读取磁盘,增加了缓存机制
  13. protected $dataCache = array();
  14. // 上次缓存时间
  15. protected $lastCacheTime = 0;
  16. // 保存数据的文件
  17. protected $dataFile = '';
  18. // 打开文件的句柄
  19. protected $dataFileHandle = null;
  20. // 缓存过期时间
  21. const CACHE_EXP_TIME = 1;
  22. /**
  23. * 构造函数
  24. * @param 配置名 $config_name
  25. */
  26. public function __construct($config_name)
  27. {
  28. $this->dataFile = \Config\Store::$storePath . "/$config_name.store.cache.php";
  29. if(!is_dir(\Config\Store::$storePath) && !@mkdir(\Config\Store::$storePath, 0777, true))
  30. {
  31. // 可能目录已经被其它进程创建
  32. clearstatcache();
  33. if(!is_dir(\Config\Store::$storePath))
  34. {
  35. // 避免狂刷日志
  36. sleep(1);
  37. throw new \Exception('cant not mkdir('.\Config\Store::$storePath.')');
  38. }
  39. }
  40. if(!is_file($this->dataFile))
  41. {
  42. touch($this->dataFile);
  43. }
  44. $this->dataFileHandle = fopen($this->dataFile, 'r+');
  45. if(!$this->dataFileHandle)
  46. {
  47. throw new \Exception("can not fopen($this->dataFile, 'r+')");
  48. }
  49. }
  50. /**
  51. * 设置
  52. * @param string $key
  53. * @param mixed $value
  54. * @param int $ttl
  55. * @return number
  56. */
  57. public function set($key, $value, $ttl = 0)
  58. {
  59. flock($this->dataFileHandle, LOCK_EX);
  60. $this->readDataFromDisk();
  61. $this->dataCache[$key] = $value;
  62. $ret = $this->writeToDisk();
  63. flock($this->dataFileHandle, LOCK_UN);
  64. return $ret;
  65. }
  66. /**
  67. * 读取
  68. * @param string $key
  69. * @param bool $use_cache
  70. * @return Ambigous <NULL, multitype:>
  71. */
  72. public function get($key, $use_cache = true)
  73. {
  74. if(!$use_cache || time() - $this->lastCacheTime > self::CACHE_EXP_TIME)
  75. {
  76. flock($this->dataFileHandle, LOCK_EX);
  77. $this->readDataFromDisk();
  78. flock($this->dataFileHandle, LOCK_UN);
  79. }
  80. return isset($this->dataCache[$key]) ? $this->dataCache[$key] : null;
  81. }
  82. /**
  83. * 删除
  84. * @param string $key
  85. * @return number
  86. */
  87. public function delete($key)
  88. {
  89. flock($this->dataFileHandle, LOCK_EX);
  90. $this->readDataFromDisk();
  91. unset($this->dataCache[$key]);
  92. $ret = $this->writeToDisk();
  93. flock($this->dataFileHandle, LOCK_UN);
  94. return $ret;
  95. }
  96. /**
  97. * 自增
  98. * @param string $key
  99. * @return boolean|multitype:
  100. */
  101. public function increment($key)
  102. {
  103. flock($this->dataFileHandle, LOCK_EX);
  104. $this->readDataFromDisk();
  105. if(!isset($this->dataCache[$key]))
  106. {
  107. flock($this->dataFileHandle, LOCK_UN);
  108. return false;
  109. }
  110. $this->dataCache[$key] ++;
  111. $this->writeToDisk();
  112. flock($this->dataFileHandle, LOCK_UN);
  113. return $this->dataCache[$key];
  114. }
  115. /**
  116. * 清零销毁存储数据
  117. */
  118. public function destroy()
  119. {
  120. @unlink($this->dataFile);
  121. }
  122. /**
  123. * 写入磁盘
  124. * @return number
  125. */
  126. protected function writeToDisk()
  127. {
  128. return file_put_contents($this->dataFile, "<?php \n return " . var_export($this->dataCache, true). ';');
  129. }
  130. /**
  131. * 从磁盘读
  132. */
  133. protected function readDataFromDisk()
  134. {
  135. $cache = include $this->dataFile;
  136. if(is_array($cache))
  137. {
  138. $this->dataCache = $cache;
  139. }
  140. $this->lastCacheTime = time();
  141. }
  142. }