php缓存技术详细介绍及php缓存实现代码

有些信息比方经常不变的,但是还是能变的信息放在缓存中以加快显示速度,这是很有价值的,所谓的缓存,通俗的理解就是一些保存在服务器端的共用信息.它是于服务器同生死的,我们在保存缓存的时候可以指定下次更新的时间的判断,比方要在5分钟更新一次

数据缓存:这里所说的数据缓存是指数据库查询PHP缓存机制,每次访问页面的时候,都会先检测相应的缓存数据是否存在,如果不存在,就连接数据库,得到数据,并把查询结果序列化后保存到文件中,以后同样的查询结果就直接从缓存表或文件中获得。

用的最广的例子看Discuz的搜索功能,把结果ID缓存到一个表中,下次搜索相同关键字时先搜索缓存表。

举个常用的方法,多表关联的时候,把附表中的内容生成数组保存到主表的一个字段中,需要的时候数组分解一下,这样的好处是只读一个表,坏处就是两个数据同步会多不少步骤,数据库永远是瓶颈,用硬盘换速度,是这个的关键点。

页面缓存:每次访问页面的时候,都会先检测相应的缓存页面文件是否存在,如果不存在,就连接数据库,得到数据,显示页面并同时生成缓存页面文件,这样下次访问的时候页面文件就发挥作用了。(模板引擎和网上常见的一些PHP缓存机制类通常有此功能)

时间触发缓存:检查文件是否存在并且时间戳小于设置的过期时间,如果文件修改的时间戳比当前时间戳减去过期时间戳大,那么就用缓存,否则更新缓存.

内容触发缓存:当插入数据或更新数据时,强制更新PHP缓存机制.

静态缓存:这里所说的静态缓存是指静态化,直接生成HTML或XML等文本文件,有更新的时候重生成一次,适合于不太变化的页面,这就不说了.

以上内容是代码级的解决方案,我直接CP别的框架,也懒得改,内容都差不多,很容易就做到,而且会几种方式一起用,但下面的内容是服务器端的缓存方案,非代码级的,要有多方的合作才能做到.

内存缓存:Memcached是高性能的,分布式的内存对象PHP缓存机制系统,用于在动态应用中减少数据库负载,提升访问速度.

php的缓冲器:有eaccelerator,apc,phpa,xcache,这个这个就不说了吧,搜索一堆一堆的,自己看啦,知道有这玩意就OK.

MYSQL缓存:这也算非代码级的,经典的数据库就是用的这种方式,看下面的运行时间,0.09xxx之类的.

我贴段根据蓝色那家伙修改后部分my.ini吧,2G的MYISAM表可以在0.05S左右,据说他前后改了有快一年.

基于反向代理的Web缓存:如Nginx,SQUID,mod_proxy(apache2以上又分为mod_proxy和mod_cache)

NGINX的例子,用google找到一些php缓存技术方法,发个PHP缓存实现,实现了apc和文件缓存,继承Cache_Abstract即可实现调用第三方的缓存工具.

参考shindig的缓存类和apc,Php代码如下:

  1. <?php
  2. class CacheException extends Exception {}
  3. /**
  4. * 缓存抽象类
  5. */
  6. abstract class Cache_Abstract {
  7. /**
  8. * 读缓存变量
  9. *
  10. * @param string $key 缓存下标
  11. * @return mixed
  12. */
  13. abstract public function fetch($key);
  14. /**
  15. * 缓存变量
  16. *
  17. * @param string $key 缓存变量下标
  18. * @param string $value 缓存变量的值
  19. * @return bool
  20. */
  21. abstract public function store($key, $value);
  22. /**
  23. * 删除缓存变量
  24. *
  25. * @param string $key 缓存下标
  26. * @return Cache_Abstract
  27. */
  28. abstract public function delete($key);
  29. /**
  30. * 清(删)除所有缓存
  31. *
  32. * @return Cache_Abstract
  33. */
  34. abstract public function clear();
  35. /**
  36. * 锁定缓存变量
  37. *
  38. * @param string $key 缓存下标
  39. * @return Cache_Abstract
  40. */
  41. abstract public function lock($key);
  42. /**
  43. * 缓存变量解锁
  44. *
  45. * @param string $key 缓存下标
  46. * @return Cache_Abstract
  47. */
  48. abstract public function unlock($key);
  49. /**
  50. * 取得缓存变量是否被锁定
  51. *
  52. * @param string $key 缓存下标
  53. * @return bool
  54. */
  55. abstract public function isLocked($key);
  56. /**
  57. * 确保不是锁定状态
  58. * 最多做$tries次睡眠等待解锁,超时则跳过并解锁
  59. *
  60. * @param string $key 缓存下标
  61. */
  62. public function checkLock($key) {
  63. if (!$this->isLocked($key)) {
  64. return $this;
  65. }
  66. $tries = 10;
  67. $count = 0;
  68. do {
  69. usleep(200);
  70. $count ++;
  71. } while ($count <= $tries && $this->isLocked($key)); // 最多做十次睡眠等待解锁,超时则跳过并解锁
  72. $this->isLocked($key) && $this->unlock($key);
  73. return $this;
  74. }
  75. }
  76. /**
  77. * APC扩展缓存实现
  78. *
  79. *
  80. * @category Mjie
  81. * @package Cache
  82. * @author 流水孟春
  83. * @copyright Copyright (c) 2008- <cmpan(at)qq.com>
  84. * @license New BSD License
  85. * @version $Id: Cache/Apc.php 版本号 2010-04-18 23:02 cmpan $
  86. */
  87. class Cache_Apc extends Cache_Abstract {
  88. protected $_prefix = 'cache.mjie.net';
  89. public function __construct() {
  90. if (!function_exists('apc_cache_info')) {
  91. throw new CacheException('apc extension didn't installed');
  92. }
  93. }
  94. /**
  95. * 保存缓存变量
  96. *
  97. * @param string $key
  98. * @param mixed $value
  99. * @return bool
  100. */
  101. public function store($key, $value) {
  102. return apc_store($this->_storageKey($key), $value);
  103. }
  104. /**
  105. * 读取缓存
  106. *
  107. * @param string $key
  108. * @return mixed
  109. */
  110. public function fetch($key) {
  111. return apc_fetch($this->_storageKey($key));
  112. }
  113. /**
  114. * 清除缓存
  115. *
  116. * @return Cache_Apc
  117. */
  118. public function clear() {
  119. apc_clear_cache();
  120. return $this;
  121. }
  122. /**
  123. * 删除缓存单元
  124. *
  125. * @return Cache_Apc
  126. */
  127. public function delete($key) {
  128. apc_delete($this->_storageKey($key));
  129. return $this;
  130. }
  131. /**
  132. * 缓存单元是否被锁定
  133. *
  134. * @param string $key
  135. * @return bool
  136. */
  137. public function isLocked($key) {
  138. if ((apc_fetch($this->_storageKey($key) . '.lock')) === false) {
  139. return false;
  140. }
  141. return true;
  142. }
  143. /**
  144. * 锁定缓存单元
  145. *
  146. * @param string $key
  147. * @return Cache_Apc
  148. */
  149. public function lock($key) {
  150. apc_store($this->_storageKey($key) . '.lock', '', 5);
  151. return $this;
  152. }
  153. /**
  154. * 缓存单元解锁
  155. *
  156. * @param string $key
  157. * @return Cache_Apc
  158. */
  159. public function unlock($key) {
  160. apc_delete($this->_storageKey($key) . '.lock');
  161. return $this;
  162. }
  163. /**
  164. * 完整缓存名
  165. *
  166. * @param string $key
  167. * @return string
  168. */
  169. private function _storageKey($key) {
  170. return $this->_prefix . '_' . $key;
  171. }
  172. }
  173. /**
  174. * 文件缓存实现
  175. *
  176. *
  177. * @category Mjie
  178. * @package Cache
  179. * @author 流水孟春
  180. * @copyright Copyright (c) 2008- <cmpan(at)qq.com>
  181. * @license New BSD License
  182. * @version $Id: Cache/File.php 版本号 2010-04-18 16:46 cmpan $
  183. */
  184. class Cache_File extends Cache_Abstract {
  185. public $useSubdir = false;
  186. protected $_cachesDir = 'cache';
  187. public function __construct() {
  188. if (defined('DATA_DIR')) {
  189. $this->_setCacheDir(DATA_DIR . '/cache');
  190. }
  191. }
  192. /**
  193. * 获取缓存文件
  194. *
  195. * @param string $key
  196. * @return string
  197. */
  198. protected function _getCacheFile($key) {
  199. $subdir = $this->useSubdir ? substr($key, 0, 2) . '/' : '';
  200. return $this->_cachesDir . '/' . $subdir . $key . '.php';
  201. }
  202. /**
  203. * 读取缓存变量
  204. * 为防止信息泄露,缓存文件格式为php文件,并以"<?php exit;?>"开头
  205. *
  206. * @param string $key 缓存下标
  207. * @return mixed
  208. */
  209. public function fetch($key) {
  210. $cacheFile = self::_getCacheFile($key);
  211. if (file_exists($cacheFile) && is_readable($cacheFile)) {
  212. // include 方式
  213. //return include $cacheFile;
  214. // 系列化方式
  215. return unserialize(@file_get_contents($cacheFile, false, NULL, 13));
  216. }
  217. return false;
  218. }
  219. /**
  220. * 缓存变量
  221. * 为防止信息泄露,缓存文件格式为php文件,并以"<?php exit;?>"开头
  222. *
  223. * @param string $key 缓存变量下标
  224. * @param string $value 缓存变量的值
  225. * @return bool
  226. */
  227. public function store($key, $value) {
  228. $cacheFile = self::_getCacheFile($key);
  229. $cacheDir = dirname($cacheFile);
  230. if(!is_dir($cacheDir)) {
  231. if(!@mkdir($cacheDir, 0755, true)) {
  232. throw new CacheException("Could not make cache directory");
  233. }
  234. }
  235. // 用include方式
  236. //return @file_put_contents($cacheFile, '<?php return ' . var_export($value, true). ';');
  237. return @file_put_contents($cacheFile, '<?php exit;?>' . serialize($value));
  238. }
  239. /**
  240. * 删除缓存变量
  241. *
  242. * @param string $key 缓存下标
  243. * @return Cache_File
  244. */
  245. public function delete($key) {
  246. if(emptyempty($key)) {
  247. throw new CacheException("Missing argument 1 for Cache_File::delete()");
  248. }
  249. $cacheFile = self::_getCacheFile($key);
  250. if(!@unlink($cacheFile)) {
  251. throw new CacheException("Cache file could not be deleted");
  252. }
  253. return $this;
  254. }
  255. /**
  256. * 缓存单元是否已经锁定
  257. *
  258. * @param string $key
  259. * @return bool
  260. */
  261. public function isLocked($key) {
  262. $cacheFile = self::_getCacheFile($key);
  263. clearstatcache();
  264. return file_exists($cacheFile . '.lock');
  265. }
  266. /**
  267. * 锁定
  268. *
  269. * @param string $key
  270. * @return Cache_File
  271. */
  272. public function lock($key) {
  273. //开源代码phpfensi.com
  274. $cacheFile = self::_getCacheFile($key);
  275. $cacheDir = dirname($cacheFile);
  276. if(!is_dir($cacheDir)) {
  277. if(!@mkdir($cacheDir, 0755, true)) {
  278. if(!is_dir($cacheDir)) {
  279. throw new CacheException("Could not make cache directory");
  280. }
  281. }
  282. }
  283. // 设定缓存锁文件的访问和修改时间
  284. @touch($cacheFile . '.lock');
  285. return $this;
  286. }
  287. /**
  288. * 解锁
  289. *
  290. * @param string $key
  291. * @return Cache_File
  292. */
  293. public function unlock($key) {
  294. $cacheFile = self::_getCacheFile($key);
  295. @unlink($cacheFile . '.lock');
  296. return
  297. ?>