codeigniter的功能纵然强大,也有不足之处。其cache模式在于针对不同的uri就会生成cache文件,如果URL中参数不同,则 cache文件就会不同,从而产生了漏洞。如果访问者构建自动生成URI,不断向服务器发起请求,就会瞬间产生大量的垃圾文件,导致系统文件臃肿。
参看CI中国论坛:脆弱的CI缓存系统,1天攻陷你的CI网站http://codeigniter.org.cn/forums/thread- 1690-1-1.html
因此如果要用到cache功能就必须找到第三方的开发库。Pear中,Cache_Lite属于较为轻量级的缓存系统,且功能强大,可以作为CI原 生cache的替代品,将其加入自定义的library文件即可完成。
步骤如下:
1. 下载Cache_Lite
http://download.pear.php.net/package/Cache_Lite-1.7.7.tgz
- 解压缩后,将Cache_Lite.php和Lite文件夹复制到 system/application/libraries中。并在Cache_Lite.php中加入:if (!defined(’BASEPATH’)) exit(’No direct script access allowed’);
2. 在要使用Cache_Lite的Controller中,加入:
- $ops = array(
- ‘cacheDir’ => BASEPATH.’/cache/’, //cache文件存储位置
- ‘lifeTime’ => 3600, //cache的有效期
- );
- // ;
- $this->load->library(”Cache_Lite”,$ops,”cc”); //cc为Cache_Lite的别名, 然后在要利用Cache的位置使用Cache_Lite自带的函数就可以拉。
如:读取缓存:$string = $this->cc->get($id);
生成缓存:$this->cc->save($outputString);
推荐一个更好的CI缓存类:MP_Cache
首先,在config.php中设置一下缓存目录,这个目录要存在且可写入
- $config['mp_cache_dir'] = 'application/mp_cache/';
现在看看代码
- /*加载library,可以放在构造函数中*/
- $this->load->library('MP_Cache');
- /*抓取名为listNews的缓存*/
- $listNews = $this->mp_cache->get('listNews');
- if($listNews===false){
- //没有缓存数据,则查询数据库
- $listNews = $this->News_model->getNewslist('guest')->result();
- //创建缓存,命名为listNews。在mp_cache目录下就生成了listNews.cache文件,内容是序列化的数据
- $this->mp_cache->write($listNews, 'listNews');
- }
- $data['listNews']= $listNews;
- $this->layout->view('news', $data);
两个注意点:
1,缓存数据,必须是data,而不是resource id。如,在使用AR后用result(),result_array()等返回的数据
2,缓存名不要重复。可以使用子文件夹分隔。如,$listNews = $this->mp_cache->get(‘news/listNews’);同样创建缓存数据片段 用$this->mp_cache->write($listNews, ‘news/listNews’);(php5下news文件夹会自动创建)
其他方法:
- $this->mp_cache->delete($filename)
删除名为$filename的cache.
- $this->mp_cache->delete_all($dirname)
删除 $dirname目录及其下所有缓存.如果$dirname没有设置,则删除所有缓存.
http://mpsimple.mijnpraktijk.com/mp_cache/user_guide.htm
MP_Cache was written as a more flexible caching solution than those offered by CodeIgniter. As such it offers you a way to cache anything from a single variable, to a SQL query or the fully generated page. MP_Cache saves these entries serialized to files and has functions to retrieve and delete these.
Additionally you can set expiration time and dependencies to force a main cache to refresh itself after one of its subcaches has been refreshed or deleted.
Installing MP_Cache
- Download the file here and unzip it to your application/libraries directory.
- Create a directory for you cache, for example application/mp_cache
- Add a value 'mp_cache_dir' to an autoloaded config file, for instance application/config/config.php and set it to the mp_cache directory relative to your index.php file.
For example: $config['mp_cache_dir'] = APPPATH.'mp_cache/'; - Optional: add a value 'mp_cache_default_expires' to the same autoloaded config file and set it to a default expiration time in seconds if you want it set by default. You can still make something never expire by setting it to 0.
- That's it, you can start using MP_Cache.
Initializing MP_Cache
Like most other classes in CodeIgniter, the MP_Cache class is initialized in your controller using the
$this->load->library function :
- $this->load->library('MP_Cache');
Once the library is loaded it will be ready for use. The MP_Cache library object you will use to call all functions is: $this->mp_cache .
Basic caching without additional settings
To just cache something within your controller or model, the usage is like this:
- $data = $this->mp_cache->get('example');
- if ($data === false)
- {
- // example model-function that generates your $data variable
- $data = $this->Pages->read($page);
- $this->mp_cache->write($data, 'example');
- }
The variable to be cached can be of any kind, though object-references will be lost when loaded from cache.
Alternative syntax for the example above
You can also use the cache in a more object oriented way. In this case you always call the set_name() method before any other because it will reset the object to its default state.
- $data = $this->mp_cache->set_name('example')->get();
- if ($data === false)
- {
- // example model-function that generates your $data variable
- $data = $this->Pages->read($page);
- $this->mp_cache->set_contents($data)->write();
- }
Warning: You can't combine the syntaxes, using the parameterized versions of write() and get() will reset the mp_cache object to prevent contamination of your current cache operation from a previous one.
Using subdirectories
For PHP5 subdirectories with virtual unlimited depth are supported, PHP4 only supports 1 level. You can set subdirectories by simply adding them in the cache name. The first line of the alternative syntax example is below in the directory "directory " which in turn is in the directory "sub ".
- $data = $this->mp_cache->set_name('sub/directory/example')->get();
Adding an expiration time
Expiration time is added when writing the cache. Exparation is set to NULL by default which means using the default expiration, you can set it to 0 for no experation (if the default is set to something larger than 0). If you want it to expire after a certain time you have to specify it in seconds after it was generated. To do so you have to change the write function like this when using the write() function with parameters:
- // Cache it for 2 hours (7200 seconds = 60 seconds * 60 minutes * 2 hours)
- $this->mp_cache->write($data, 'example', 7200);
Or do it by using the set_expires() function:
- $this->mp_cache->set_name('example')->set_contents($data)->set_expires(7200)->write();
Adding dependencies
You can add cache file on which the expiration of the current cache file is dependend. When one of those files has been deleted or refreshed after the current cache was made, the current cache will be deleted. So lets say we have a menu called mainmenu which we have cached in a subdirectory called menus . Using the parameterized write() function you can add the dependency like this (expiration set to none):
- $this->mp_cache->write($data, 'example', null, array('menus/mainmenu'));
Or using the set_dependencies() function (which takes an array or a string):
- $this->mp_cache->set_name('example')->set_contents($data)->set_dependencies('menus/mainmenu')->write();
Deleting individual caches
You can delete cache by using the delete() function:
- $this->mp_cache->delete('example');
Or in the alternative way:
- $this->mp_cache->set_name('example')->delete();
Deleting the entire cache or subdirectories of it
To delete the entire cache you can use the delete_all() function:
- $this->mp_cache->delete_all();
Or you can delete a subdirectory of the main cache, like all the menus from the example for dependencies:
- $this->mp_cache->delete_all('menus');
This will delete all the files in the subdirectory menus of the main cache. All the subdirectories of the menusdirectory and files within them will also be deleted.
Full functions overview
reset()
Resets the current state of the mp_cache object. It is called automatically from the set_name() function or when the write() & get() functions are used with parameters. This is done to prevent any previous usage of the mp_cache object from contaminating your current usage with settings you would expect to be the default ones.
- $this->mp_cache->reset();
set_name() & get_name()
Sets or returns the full filename of the cache.
Warning: the set_name() function automatically calls reset(), so always use it as the first function when using the alternative syntax.
- $this->mp_cache->set_name('example');
- // after this is set the variable below will be set to the string 'example'
- $var = $this->mp_cache->get_name();
set_contents() & get_contents()
Sets or returns the contents you are caching or retrieving.
- $this->mp_cache->set_contents(array(1,2,3,4,5));
- // The function below will return the array set above
- $array = $this->mp_cache->get_contents();
set_dependencies(), add_dependencies() & get_dependencies()
Sets the dependencies, adds to the current dependencies or returns the set dependencies.
- $this->mp_cache->set_dependencies('example');
- // this sets the dependencies to the 'example' cache file
- $this->mp_cache->set_dependencies(array('cachefile1', 'cachefile2'));
- // this has overwritten the first statement and set the dependencies to 'cachefile1' & 'cachefile2'
- $this->mp_cache->add_dependencies('example')
- // this has added 'example' as a dependency in addition to 'cachefile1' & 'cachefile2'
All functions take both strings and arrays of strings.
set_expires() & get_expires()
Sets the expiration time and retrieves the time on which the cache will expire.
- $this->mp_cache->set_expires(7200);
- // sets the expiration to a timestamp 2 hours from now
- $expires = $this->mp_cache->get_expires();
- // $expires is set to the timestamp 2 hours from now as defined by set_expires()
get_created()
Returns the timestamp from the moment the retrieved cache was created, returns NULL when used while writing cache.
- $created_on = $this->mp_cache->get_created();