output_cache_library.php
1 <?php
2
/**
3  * File-based Output Cache Library
4  *
5  * @author Zhou Yuan <yuanzhou19@gmail.com>
6  * @link http://www.infopotato.com/
7  * @copyright Copyright &copy; 2009-2011 Zhou Yuan
8  * @license http://www.opensource.org/licenses/mit-license.php MIT Licence
9  * @link        based on http://www.jongales.com/blog/2009/02/18/simple-file-based-php-cache-class/
10  * @link        based on http://www.rooftopsolutions.nl/article/107
11  */
12
class Output_Cache_Library {  
13     
14     
/**
15      * The cache dir. The dir should end with DIRECTORY_SEPARATOR
16      * 
17      * @var string 
18      */
19     
private $_dir;
20     
21     
/**
22      * Constructor
23      *
24      * @param array $config['cache_dir']
25      *
26      */    
27     
public function __construct(array $config NULL) { 
28         if (
count($config) > 0) {
29             if (isset(
$config['cache_dir'])) {
30                 
$this->_dir $config['cache_dir'];
31             }
32         }
33     }
34     
35     
/**
36      * Find the filename for a certain key 
37      *
38      * @param    string
39      * @return    string
40      */
41     
private function _name($key) {  
42         return (
$this->_dir).sha1($key);  
43     }  
44     
45     
/**
46      * Get the cached file for a certain key 
47      * 
48      * @param    $key string
49      * @return    mixed - FALSE|string (cached data)
50      */
51     
public function get($key) {  
52         if ( ! 
is_dir($this->_dir)) {
53             return 
FALSE;   
54         }
55         
$cache_path $this->_name($key);  
56
57         if ( ! 
file_exists($cache_path) || ! is_readable($cache_path)) {
58             return 
FALSE;   
59         }
60         
// Open for reading only; use 'b' to force binary mode
61         
if ( ! $fp fopen($cache_path'rb')) {
62             return 
FALSE;  
63         }
64         
// To acquire a shared lock (reader)
65         
flock($fpLOCK_SH);  
66         
// file_get_contents() is much faster than fread()
67         // $cached_data is an array contains [0] => expire time, [1] => cached content
68         
$cached_data unserialize(file_get_contents($cache_path));  
69         
// To release a lock (shared or exclusive)
70         
flock($fpLOCK_UN);
71         
// The lock is released also by fclose() (which is also called automatically when script finished).
72         
fclose($fp);
73         
74         if (
$cached_data) {
75             
// Check if the cached file was expired 
76             
if (time() > $cached_data[0]) { 
77                 
$this->clear($key);  
78                 return 
FALSE;
79             }
80             return 
$cached_data[1]; 
81         } 
82         return 
FALSE
83     }  
84     
85     
/**
86      * Create the cache file for a certain key 
87      * 
88      * @param    $key string
89      * @param    $data string the data to be cached
90      * @param    $ttl integer - time to life (seconds)
91      * @return    boolean
92      */
93     
public function set($key$data$ttl 3600) {  
94         if ( ! 
is_dir($this->_dir) || ! $this->_is_really_writable($this->_dir)) {
95             return 
FALSE;  
96         }
97         
$cache_path $this->_name($key);  
98         
99         
// Open for writing only; use 'b' to force binary mode
100         
if ( ! $fp fopen($cache_path'wb')) {
101             return 
FALSE;    
102         }
103         
// To acquire an exclusive lock (writer)
104         
if (flock($fpLOCK_EX)) {      
105             
// fwrite is faster than file_put_contents() 
106             
fwrite($fpserialize(array(time() + $ttl$data)));  
107             
// To release a lock (shared or exclusive)
108             
flock($fpLOCK_UN);
109             
// The lock is released also by fclose() (which is also called automatically when script finished).
110             
fclose($fp); 
111         } else {
112             return 
FALSE;  
113         }
114         
chmod($cache_path0777); 
115         return 
TRUE;    
116     }  
117     
118     
/**
119      * Delete the cached file for a certain key 
120      *
121      * @param    $key string
122      * @return    boolean
123      */
124     
public function clear($key) {  
125         
$cache_path $this->_name($key);  
126         if (
file_exists($cache_path)) {  
127             
// Deletes cached file
128             
unlink($cache_path);  
129             return 
TRUE;  
130         }  
131         return 
FALSE;  
132     }  
133     
134     
/**
135      * Tests for file writability
136      *
137      * is_writable() returns TRUE on Windows servers when you really can't write to 
138      * the file, based on the read-only attribute.  is_writable() is also unreliable
139      * on Unix servers if safe_mode is on. 
140      *
141      * @return    void
142      */
143     
private function _is_really_writable($file) {    
144         
// If we're on a Unix server with safe_mode off we call is_writable
145         
if (DIRECTORY_SEPARATOR == '/' && @ini_get("safe_mode") == FALSE) {
146             return 
is_writable($file);
147         }
148
149         
// For windows servers and safe_mode "on" installations we'll actually
150         // write a file then read it.  Bah...
151         
if (is_dir($file)) {
152             
$file rtrim($file'/').'/'.md5(rand(1100));
153
154             if ((
$fp = @fopen($file'ab')) === FALSE) {
155                 return 
FALSE;
156             }
157
158             
fclose($fp);
159             @
chmod($file0777);
160             @
unlink($file);
161             return 
TRUE;
162         } elseif ((
$fp = @fopen($file'ab')) === FALSE) {
163             return 
FALSE;
164         }
165
166         
fclose($fp);
167         return 
TRUE;
168     }
169
170  
171
/* End of file: ./system/libraries/output_cache/output_cache_library.php */

Page URI: http://www.infopotato.com/index.php/code/library/output_cache/