PageRenderTime 71ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/4.9/includes/PEAR/Cache/Lite.php

http://miacms.googlecode.com/
PHP | 830 lines | 385 code | 56 blank | 389 comment | 85 complexity | e656718d26921a450b97fb50a2919c01 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0, LGPL-2.0
  1. <?php
  2. /**
  3. * Fast, light and safe Cache Class
  4. *
  5. * Cache_Lite is a fast, light and safe cache system. It's optimized
  6. * for file containers. It is fast and safe (because it uses file
  7. * locking and/or anti-corruption tests).
  8. *
  9. * There are some examples in the 'docs/examples' file
  10. * Technical choices are described in the 'docs/technical' file
  11. *
  12. * Memory Caching is from an original idea of
  13. * Mike BENOIT <ipso@snappymail.ca>
  14. *
  15. * Nota : A chinese documentation (thanks to RainX <china_1982@163.com>) is
  16. * available at :
  17. * http://rainx.phpmore.com/manual/cache_lite.html
  18. *
  19. * @package Cache_Lite
  20. * @category Caching
  21. * @version $Id: Lite.php,v 1.50 2008/04/13 14:41:23 tacker Exp $
  22. * @author Fabien MARTY <fab@php.net>
  23. */
  24. /** ensure this file is being included by a parent file */
  25. defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' );
  26. define('CACHE_LITE_ERROR_RETURN', 1);
  27. define('CACHE_LITE_ERROR_DIE', 8);
  28. class Cache_Lite
  29. {
  30. // --- Private properties ---
  31. /**
  32. * Directory where to put the cache files
  33. * (make sure to add a trailing slash)
  34. *
  35. * @var string $_cacheDir
  36. */
  37. var $_cacheDir = '/tmp/';
  38. /**
  39. * Enable / disable caching
  40. *
  41. * (can be very usefull for the debug of cached scripts)
  42. *
  43. * @var boolean $_caching
  44. */
  45. var $_caching = true;
  46. /**
  47. * Cache lifetime (in seconds)
  48. *
  49. * If null, the cache is valid forever.
  50. *
  51. * @var int $_lifeTime
  52. */
  53. var $_lifeTime = 3600;
  54. /**
  55. * Enable / disable fileLocking
  56. *
  57. * (can avoid cache corruption under bad circumstances)
  58. *
  59. * @var boolean $_fileLocking
  60. */
  61. var $_fileLocking = true;
  62. /**
  63. * Timestamp of the last valid cache
  64. *
  65. * @var int $_refreshTime
  66. */
  67. var $_refreshTime;
  68. /**
  69. * File name (with path)
  70. *
  71. * @var string $_file
  72. */
  73. var $_file;
  74. /**
  75. * File name (without path)
  76. *
  77. * @var string $_fileName
  78. */
  79. var $_fileName;
  80. /**
  81. * Enable / disable write control (the cache is read just after writing to detect corrupt entries)
  82. *
  83. * Enable write control will lightly slow the cache writing but not the cache reading
  84. * Write control can detect some corrupt cache files but maybe it's not a perfect control
  85. *
  86. * @var boolean $_writeControl
  87. */
  88. var $_writeControl = true;
  89. /**
  90. * Enable / disable read control
  91. *
  92. * If enabled, a control key is embeded in cache file and this key is compared with the one
  93. * calculated after the reading.
  94. *
  95. * @var boolean $_writeControl
  96. */
  97. var $_readControl = true;
  98. /**
  99. * Type of read control (only if read control is enabled)
  100. *
  101. * Available values are :
  102. * 'md5' for a md5 hash control (best but slowest)
  103. * 'crc32' for a crc32 hash control (lightly less safe but faster, better choice)
  104. * 'strlen' for a length only test (fastest)
  105. *
  106. * @var boolean $_readControlType
  107. */
  108. var $_readControlType = 'crc32';
  109. /**
  110. * Pear error mode (when raiseError is called)
  111. *
  112. * (see PEAR doc)
  113. *
  114. * @see setToDebug()
  115. * @var int $_pearErrorMode
  116. */
  117. var $_pearErrorMode = CACHE_LITE_ERROR_RETURN;
  118. /**
  119. * Current cache id
  120. *
  121. * @var string $_id
  122. */
  123. var $_id;
  124. /**
  125. * Current cache group
  126. *
  127. * @var string $_group
  128. */
  129. var $_group;
  130. /**
  131. * Enable / Disable "Memory Caching"
  132. *
  133. * NB : There is no lifetime for memory caching !
  134. *
  135. * @var boolean $_memoryCaching
  136. */
  137. var $_memoryCaching = false;
  138. /**
  139. * Enable / Disable "Only Memory Caching"
  140. * (be carefull, memory caching is "beta quality")
  141. *
  142. * @var boolean $_onlyMemoryCaching
  143. */
  144. var $_onlyMemoryCaching = false;
  145. /**
  146. * Memory caching array
  147. *
  148. * @var array $_memoryCachingArray
  149. */
  150. var $_memoryCachingArray = array();
  151. /**
  152. * Memory caching counter
  153. *
  154. * @var int $memoryCachingCounter
  155. */
  156. var $_memoryCachingCounter = 0;
  157. /**
  158. * Memory caching limit
  159. *
  160. * @var int $memoryCachingLimit
  161. */
  162. var $_memoryCachingLimit = 1000;
  163. /**
  164. * File Name protection
  165. *
  166. * if set to true, you can use any cache id or group name
  167. * if set to false, it can be faster but cache ids and group names
  168. * will be used directly in cache file names so be carefull with
  169. * special characters...
  170. *
  171. * @var boolean $fileNameProtection
  172. */
  173. var $_fileNameProtection = true;
  174. /**
  175. * Enable / disable automatic serialization
  176. *
  177. * it can be used to save directly datas which aren't strings
  178. * (but it's slower)
  179. *
  180. * @var boolean $_serialize
  181. */
  182. var $_automaticSerialization = false;
  183. /**
  184. * Disable / Tune the automatic cleaning process
  185. *
  186. * The automatic cleaning process destroy too old (for the given life time)
  187. * cache files when a new cache file is written.
  188. * 0 => no automatic cache cleaning
  189. * 1 => systematic cache cleaning
  190. * x (integer) > 1 => automatic cleaning randomly 1 times on x cache write
  191. *
  192. * @var int $_automaticCleaning
  193. */
  194. var $_automaticCleaningFactor = 0;
  195. /**
  196. * Nested directory level
  197. *
  198. * Set the hashed directory structure level. 0 means "no hashed directory
  199. * structure", 1 means "one level of directory", 2 means "two levels"...
  200. * This option can speed up Cache_Lite only when you have many thousands of
  201. * cache file. Only specific benchs can help you to choose the perfect value
  202. * for you. Maybe, 1 or 2 is a good start.
  203. *
  204. * @var int $_hashedDirectoryLevel
  205. */
  206. var $_hashedDirectoryLevel = 0;
  207. /**
  208. * Umask for hashed directory structure
  209. *
  210. * @var int $_hashedDirectoryUmask
  211. */
  212. var $_hashedDirectoryUmask = 0700;
  213. /**
  214. * API break for error handling in CACHE_LITE_ERROR_RETURN mode
  215. *
  216. * In CACHE_LITE_ERROR_RETURN mode, error handling was not good because
  217. * for example save() method always returned a boolean (a PEAR_Error object
  218. * would be better in CACHE_LITE_ERROR_RETURN mode). To correct this without
  219. * breaking the API, this option (false by default) can change this handling.
  220. *
  221. * @var boolean
  222. */
  223. var $_errorHandlingAPIBreak = false;
  224. // --- Public methods ---
  225. /**
  226. * Constructor
  227. *
  228. * $options is an assoc. Available options are :
  229. * $options = array(
  230. * 'cacheDir' => directory where to put the cache files (string),
  231. * 'caching' => enable / disable caching (boolean),
  232. * 'lifeTime' => cache lifetime in seconds (int),
  233. * 'fileLocking' => enable / disable fileLocking (boolean),
  234. * 'writeControl' => enable / disable write control (boolean),
  235. * 'readControl' => enable / disable read control (boolean),
  236. * 'readControlType' => type of read control 'crc32', 'md5', 'strlen' (string),
  237. * 'pearErrorMode' => pear error mode (when raiseError is called) (cf PEAR doc) (int),
  238. * 'memoryCaching' => enable / disable memory caching (boolean),
  239. * 'onlyMemoryCaching' => enable / disable only memory caching (boolean),
  240. * 'memoryCachingLimit' => max nbr of records to store into memory caching (int),
  241. * 'fileNameProtection' => enable / disable automatic file name protection (boolean),
  242. * 'automaticSerialization' => enable / disable automatic serialization (boolean),
  243. * 'automaticCleaningFactor' => distable / tune automatic cleaning process (int),
  244. * 'hashedDirectoryLevel' => level of the hashed directory system (int),
  245. * 'hashedDirectoryUmask' => umask for hashed directory structure (int),
  246. * 'errorHandlingAPIBreak' => API break for better error handling ? (boolean)
  247. * );
  248. *
  249. * @param array $options options
  250. * @access public
  251. */
  252. function Cache_Lite($options = array(NULL))
  253. {
  254. foreach($options as $key => $value) {
  255. $this->setOption($key, $value);
  256. }
  257. }
  258. /**
  259. * Generic way to set a Cache_Lite option
  260. *
  261. * see Cache_Lite constructor for available options
  262. *
  263. * @var string $name name of the option
  264. * @var mixed $value value of the option
  265. * @access public
  266. */
  267. function setOption($name, $value)
  268. {
  269. $availableOptions = array('errorHandlingAPIBreak', 'hashedDirectoryUmask', 'hashedDirectoryLevel', 'automaticCleaningFactor', 'automaticSerialization', 'fileNameProtection', 'memoryCaching', 'onlyMemoryCaching', 'memoryCachingLimit', 'cacheDir', 'caching', 'lifeTime', 'fileLocking', 'writeControl', 'readControl', 'readControlType', 'pearErrorMode');
  270. if (in_array($name, $availableOptions)) {
  271. $property = '_'.$name;
  272. $this->$property = $value;
  273. }
  274. }
  275. /**
  276. * Test if a cache is available and (if yes) return it
  277. *
  278. * @param string $id cache id
  279. * @param string $group name of the cache group
  280. * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
  281. * @return string data of the cache (else : false)
  282. * @access public
  283. */
  284. function get($id, $group = 'default', $doNotTestCacheValidity = false)
  285. {
  286. $this->_id = $id;
  287. $this->_group = $group;
  288. $data = false;
  289. if ($this->_caching) {
  290. $this->_setRefreshTime();
  291. $this->_setFileName($id, $group);
  292. clearstatcache();
  293. if ($this->_memoryCaching) {
  294. if (isset($this->_memoryCachingArray[$this->_file])) {
  295. if ($this->_automaticSerialization) {
  296. return unserialize($this->_memoryCachingArray[$this->_file]);
  297. }
  298. return $this->_memoryCachingArray[$this->_file];
  299. }
  300. if ($this->_onlyMemoryCaching) {
  301. return false;
  302. }
  303. }
  304. if (($doNotTestCacheValidity) || (is_null($this->_refreshTime))) {
  305. if (file_exists($this->_file)) {
  306. $data = $this->_read();
  307. }
  308. } else {
  309. if ((file_exists($this->_file)) && (@filemtime($this->_file) > $this->_refreshTime)) {
  310. $data = $this->_read();
  311. }
  312. }
  313. if (($data) and ($this->_memoryCaching)) {
  314. $this->_memoryCacheAdd($data);
  315. }
  316. if (($this->_automaticSerialization) and (is_string($data))) {
  317. $data = unserialize($data);
  318. }
  319. return $data;
  320. }
  321. return false;
  322. }
  323. /**
  324. * Save some data in a cache file
  325. *
  326. * @param string $data data to put in cache (can be another type than strings if automaticSerialization is on)
  327. * @param string $id cache id
  328. * @param string $group name of the cache group
  329. * @return boolean true if no problem (else : false or a PEAR_Error object)
  330. * @access public
  331. */
  332. function save($data, $id = NULL, $group = 'default')
  333. {
  334. if ($this->_caching) {
  335. if ($this->_automaticSerialization) {
  336. $data = serialize($data);
  337. }
  338. if (isset($id)) {
  339. $this->_setFileName($id, $group);
  340. }
  341. if ($this->_memoryCaching) {
  342. $this->_memoryCacheAdd($data);
  343. if ($this->_onlyMemoryCaching) {
  344. return true;
  345. }
  346. }
  347. if ($this->_automaticCleaningFactor>0) {
  348. $rand = rand(1, $this->_automaticCleaningFactor);
  349. if ($rand==1) {
  350. $this->clean(false, 'old');
  351. }
  352. }
  353. if ($this->_writeControl) {
  354. $res = $this->_writeAndControl($data);
  355. if (is_bool($res)) {
  356. if ($res) {
  357. return true;
  358. }
  359. // if $res if false, we need to invalidate the cache
  360. @touch($this->_file, time() - 2*abs($this->_lifeTime));
  361. return false;
  362. }
  363. } else {
  364. $res = $this->_write($data);
  365. }
  366. if (is_object($res)) {
  367. // $res is a PEAR_Error object
  368. if (!($this->_errorHandlingAPIBreak)) {
  369. return false; // we return false (old API)
  370. }
  371. }
  372. return $res;
  373. }
  374. return false;
  375. }
  376. /**
  377. * Remove a cache file
  378. *
  379. * @param string $id cache id
  380. * @param string $group name of the cache group
  381. * @return boolean true if no problem
  382. * @access public
  383. */
  384. function remove($id, $group = 'default')
  385. {
  386. $this->_setFileName($id, $group);
  387. if ($this->_memoryCaching) {
  388. if (isset($this->_memoryCachingArray[$this->_file])) {
  389. unset($this->_memoryCachingArray[$this->_file]);
  390. $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
  391. }
  392. if ($this->_onlyMemoryCaching) {
  393. return true;
  394. }
  395. }
  396. return $this->_unlink($this->_file);
  397. }
  398. /**
  399. * Clean the cache
  400. *
  401. * if no group is specified all cache files will be destroyed
  402. * else only cache files of the specified group will be destroyed
  403. *
  404. * @param string $group name of the cache group
  405. * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup',
  406. * 'callback_myFunction'
  407. * @return boolean true if no problem
  408. * @access public
  409. */
  410. function clean($group = false, $mode = 'ingroup')
  411. {
  412. return $this->_cleanDir($this->_cacheDir, $group, $mode);
  413. }
  414. /**
  415. * Set to debug mode
  416. *
  417. * When an error is found, the script will stop and the message will be displayed
  418. * (in debug mode only).
  419. *
  420. * @access public
  421. */
  422. function setToDebug()
  423. {
  424. $this->setOption('pearErrorMode', CACHE_LITE_ERROR_DIE);
  425. }
  426. /**
  427. * Set a new life time
  428. *
  429. * @param int $newLifeTime new life time (in seconds)
  430. * @access public
  431. */
  432. function setLifeTime($newLifeTime)
  433. {
  434. $this->_lifeTime = $newLifeTime;
  435. $this->_setRefreshTime();
  436. }
  437. /**
  438. * Save the state of the caching memory array into a cache file cache
  439. *
  440. * @param string $id cache id
  441. * @param string $group name of the cache group
  442. * @access public
  443. */
  444. function saveMemoryCachingState($id, $group = 'default')
  445. {
  446. if ($this->_caching) {
  447. $array = array(
  448. 'counter' => $this->_memoryCachingCounter,
  449. 'array' => $this->_memoryCachingArray
  450. );
  451. $data = serialize($array);
  452. $this->save($data, $id, $group);
  453. }
  454. }
  455. /**
  456. * Load the state of the caching memory array from a given cache file cache
  457. *
  458. * @param string $id cache id
  459. * @param string $group name of the cache group
  460. * @param boolean $doNotTestCacheValidity if set to true, the cache validity won't be tested
  461. * @access public
  462. */
  463. function getMemoryCachingState($id, $group = 'default', $doNotTestCacheValidity = false)
  464. {
  465. if ($this->_caching) {
  466. if ($data = $this->get($id, $group, $doNotTestCacheValidity)) {
  467. $array = unserialize($data);
  468. $this->_memoryCachingCounter = $array['counter'];
  469. $this->_memoryCachingArray = $array['array'];
  470. }
  471. }
  472. }
  473. /**
  474. * Return the cache last modification time
  475. *
  476. * BE CAREFUL : THIS METHOD IS FOR HACKING ONLY !
  477. *
  478. * @return int last modification time
  479. */
  480. function lastModified()
  481. {
  482. return @filemtime($this->_file);
  483. }
  484. /**
  485. * Trigger a PEAR error
  486. *
  487. * To improve performances, the PEAR.php file is included dynamically.
  488. * The file is so included only when an error is triggered. So, in most
  489. * cases, the file isn't included and perfs are much better.
  490. *
  491. * @param string $msg error message
  492. * @param int $code error code
  493. * @access public
  494. */
  495. function raiseError($msg, $code)
  496. {
  497. global $mosConfig_absolute_path;
  498. include_once($mosConfig_absolute_path . '/includes/PEAR/PEAR.php');
  499. return PEAR::raiseError($msg, $code, $this->_pearErrorMode);
  500. }
  501. /**
  502. * Extend the life of a valid cache file
  503. *
  504. * see http://pear.php.net/bugs/bug.php?id=6681
  505. *
  506. * @access public
  507. */
  508. function extendLife()
  509. {
  510. @touch($this->_file);
  511. }
  512. // --- Private methods ---
  513. /**
  514. * Compute & set the refresh time
  515. *
  516. * @access private
  517. */
  518. function _setRefreshTime()
  519. {
  520. if (is_null($this->_lifeTime)) {
  521. $this->_refreshTime = null;
  522. } else {
  523. $this->_refreshTime = time() - $this->_lifeTime;
  524. }
  525. }
  526. /**
  527. * Remove a file
  528. *
  529. * @param string $file complete file path and name
  530. * @return boolean true if no problem
  531. * @access private
  532. */
  533. function _unlink($file)
  534. {
  535. if (!@unlink($file)) {
  536. return $this->raiseError('Cache_Lite : Unable to remove cache !', -3);
  537. }
  538. return true;
  539. }
  540. /**
  541. * Recursive function for cleaning cache file in the given directory
  542. *
  543. * @param string $dir directory complete path (with a trailing slash)
  544. * @param string $group name of the cache group
  545. * @param string $mode flush cache mode : 'old', 'ingroup', 'notingroup',
  546. 'callback_myFunction'
  547. * @return boolean true if no problem
  548. * @access private
  549. */
  550. function _cleanDir($dir, $group = false, $mode = 'ingroup')
  551. {
  552. if ($this->_fileNameProtection) {
  553. $motif = ($group) ? 'cache_'.md5($group).'_' : 'cache_';
  554. } else {
  555. $motif = ($group) ? 'cache_'.$group.'_' : 'cache_';
  556. }
  557. if ($this->_memoryCaching) {
  558. foreach($this->_memoryCachingArray as $key => $v) {
  559. if (strpos($key, $motif) !== false) {
  560. unset($this->_memoryCachingArray[$key]);
  561. $this->_memoryCachingCounter = $this->_memoryCachingCounter - 1;
  562. }
  563. }
  564. if ($this->_onlyMemoryCaching) {
  565. return true;
  566. }
  567. }
  568. if (!($dh = opendir($dir))) {
  569. return $this->raiseError('Cache_Lite : Unable to open cache directory !', -4);
  570. }
  571. $result = true;
  572. while ($file = readdir($dh)) {
  573. if (($file != '.') && ($file != '..')) {
  574. if (substr($file, 0, 6)=='cache_') {
  575. $file2 = $dir . $file;
  576. if (is_file($file2)) {
  577. switch (substr($mode, 0, 9)) {
  578. case 'old':
  579. // files older than lifeTime get deleted from cache
  580. if (!is_null($this->_lifeTime)) {
  581. if ((mktime() - @filemtime($file2)) > $this->_lifeTime) {
  582. $result = ($result and ($this->_unlink($file2)));
  583. }
  584. }
  585. break;
  586. case 'notingrou':
  587. if (strpos($file2, $motif) === false) {
  588. $result = ($result and ($this->_unlink($file2)));
  589. }
  590. break;
  591. case 'callback_':
  592. $func = substr($mode, 9, strlen($mode) - 9);
  593. if ($func($file2, $group)) {
  594. $result = ($result and ($this->_unlink($file2)));
  595. }
  596. break;
  597. case 'ingroup':
  598. default:
  599. if (strpos($file2, $motif) !== false) {
  600. $result = ($result and ($this->_unlink($file2)));
  601. }
  602. break;
  603. }
  604. }
  605. if ((is_dir($file2)) and ($this->_hashedDirectoryLevel>0)) {
  606. $result = ($result and ($this->_cleanDir($file2 . '/', $group, $mode)));
  607. }
  608. }
  609. }
  610. }
  611. return $result;
  612. }
  613. /**
  614. * Add some date in the memory caching array
  615. *
  616. * @param string $data data to cache
  617. * @access private
  618. */
  619. function _memoryCacheAdd($data)
  620. {
  621. $this->_memoryCachingArray[$this->_file] = $data;
  622. if ($this->_memoryCachingCounter >= $this->_memoryCachingLimit) {
  623. list($key, ) = each($this->_memoryCachingArray);
  624. unset($this->_memoryCachingArray[$key]);
  625. } else {
  626. $this->_memoryCachingCounter = $this->_memoryCachingCounter + 1;
  627. }
  628. }
  629. /**
  630. * Make a file name (with path)
  631. *
  632. * @param string $id cache id
  633. * @param string $group name of the group
  634. * @access private
  635. */
  636. function _setFileName($id, $group)
  637. {
  638. if ($this->_fileNameProtection) {
  639. $suffix = 'cache_'.md5($group).'_'.md5($id);
  640. } else {
  641. $suffix = 'cache_'.$group.'_'.$id;
  642. }
  643. $root = $this->_cacheDir;
  644. if ($this->_hashedDirectoryLevel>0) {
  645. $hash = md5($suffix);
  646. for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
  647. $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
  648. }
  649. }
  650. $this->_fileName = $suffix;
  651. $this->_file = $root.$suffix;
  652. }
  653. /**
  654. * Read the cache file and return the content
  655. *
  656. * @return string content of the cache file (else : false or a PEAR_Error object)
  657. * @access private
  658. */
  659. function _read()
  660. {
  661. $fp = @fopen($this->_file, "rb");
  662. if ($this->_fileLocking) @flock($fp, LOCK_SH);
  663. if ($fp) {
  664. clearstatcache();
  665. $length = @filesize($this->_file);
  666. $mqr = get_magic_quotes_runtime();
  667. set_magic_quotes_runtime(0);
  668. if ($this->_readControl) {
  669. $hashControl = @fread($fp, 32);
  670. $length = $length - 32;
  671. }
  672. if ($length) {
  673. $data = @fread($fp, $length);
  674. } else {
  675. $data = '';
  676. }
  677. set_magic_quotes_runtime($mqr);
  678. if ($this->_fileLocking) @flock($fp, LOCK_UN);
  679. @fclose($fp);
  680. if ($this->_readControl) {
  681. $hashData = $this->_hash($data, $this->_readControlType);
  682. if ($hashData != $hashControl) {
  683. if (!(is_null($this->_lifeTime))) {
  684. @touch($this->_file, time() - 2*abs($this->_lifeTime));
  685. } else {
  686. @unlink($this->_file);
  687. }
  688. return false;
  689. }
  690. }
  691. return $data;
  692. }
  693. return $this->raiseError('Cache_Lite : Unable to read cache !', -2);
  694. }
  695. /**
  696. * Write the given data in the cache file
  697. *
  698. * @param string $data data to put in cache
  699. * @return boolean true if ok (a PEAR_Error object else)
  700. * @access private
  701. */
  702. function _write($data)
  703. {
  704. if ($this->_hashedDirectoryLevel > 0) {
  705. $hash = md5($this->_fileName);
  706. $root = $this->_cacheDir;
  707. for ($i=0 ; $i<$this->_hashedDirectoryLevel ; $i++) {
  708. $root = $root . 'cache_' . substr($hash, 0, $i + 1) . '/';
  709. if (!(@is_dir($root))) {
  710. @mkdir($root, $this->_hashedDirectoryUmask);
  711. }
  712. }
  713. }
  714. $fp = @fopen($this->_file, "wb");
  715. if ($fp) {
  716. if ($this->_fileLocking) @flock($fp, LOCK_EX);
  717. if ($this->_readControl) {
  718. @fwrite($fp, $this->_hash($data, $this->_readControlType), 32);
  719. }
  720. $mqr = get_magic_quotes_runtime();
  721. set_magic_quotes_runtime(0);
  722. @fwrite($fp, $data);
  723. set_magic_quotes_runtime($mqr);
  724. if ($this->_fileLocking) @flock($fp, LOCK_UN);
  725. @fclose($fp);
  726. return true;
  727. }
  728. return $this->raiseError('Cache_Lite : Unable to write cache file : '.$this->_file, -1);
  729. }
  730. /**
  731. * Write the given data in the cache file and control it just after to avoir corrupted cache entries
  732. *
  733. * @param string $data data to put in cache
  734. * @return boolean true if the test is ok (else : false or a PEAR_Error object)
  735. * @access private
  736. */
  737. function _writeAndControl($data)
  738. {
  739. $result = $this->_write($data);
  740. if (is_object($result)) {
  741. return $result; # We return the PEAR_Error object
  742. }
  743. $dataRead = $this->_read();
  744. if (is_object($dataRead)) {
  745. return $dataRead; # We return the PEAR_Error object
  746. }
  747. if ((is_bool($dataRead)) && (!$dataRead)) {
  748. return false;
  749. }
  750. return ($dataRead==$data);
  751. }
  752. /**
  753. * Make a control key with the string containing datas
  754. *
  755. * @param string $data data
  756. * @param string $controlType type of control 'md5', 'crc32' or 'strlen'
  757. * @return string control key
  758. * @access private
  759. */
  760. function _hash($data, $controlType)
  761. {
  762. switch ($controlType) {
  763. case 'md5':
  764. return md5($data);
  765. case 'crc32':
  766. return sprintf('% 32d', crc32($data));
  767. case 'strlen':
  768. return sprintf('% 32d', strlen($data));
  769. default:
  770. return $this->raiseError('Unknown controlType ! (available values are only \'md5\', \'crc32\', \'strlen\')', -5);
  771. }
  772. }
  773. }
  774. ?>