PHPSA中实现缓存方案 (phpsa系列教程之五)
大师兄(teacherli(-at-)gmail.com) 2005-12-19
前几节将PHPSA的一些基本的用法给大家介绍了一下, 这节来看看如果在PHPSA中使用缓存方案. 我们知道, 缓存的级别有两种, 一种为对页面进行缓存, 另一种对数据库提取数据进行缓存, 我们这里主要考虑对页面的缓存方案. 页面缓存基本的原理就是将页面内容缓存到文件, 当第一次缓存后, 在缓存的有效时间内再次请求同一URL时将直接由缓存文件中调出数据, 生成静态页实际就是一种典型的缓存机制, 不过它缓存后会由用户直接请求, 而不再经过PHP进行缓存内容的提取显示. 现在很多的论坛都采用缓存技术来应对大并发用户请求, 它的方案就类似我现在讲的这种方案, 将页面内容先缓存到文件中, 在用户下次进行请求时程序不进行数据库查询而是直接由文件中取出已经缓存的页面内容.
举一个简单的例子: http://abc.com/index.php, index.php文件为首页, 里边包含着大量的新闻性数据, 新闻性的数据又分为很多的子类, 这样, 要想显示给用户完整体的一个首页, index.php中就要对数据库进行多次请求, 这里设定为N次, 而网站又同时并发访问M个用户, 这样, 在单位时间内程序就需要执行M次数据库连接N*M次数据请求, 考虑到首页主要显示一些动态性不高的新闻, 这时我们就可以使用缓存到文件的办法, 在第一次执行index.php时取得index.php显示给用户的完整页面内容, 然后将它写入一个缓存文件index.cache, 在缓存的有效时间内用户再次访问index.php的时候程序使用文件读写方式由index.cache文件中取出所有内容, 然后显示给用户.
PHPSA框架将显示与动作分离, 通过集成的缓存类Cache可以很轻松的完成这种缓存方案, 先来看看Cache类中主要定义的方法:
缓存主要是对于程序的界面进行缓存, 因而我们要在Action类的doView()方法中实现缓存, 来看defaultAction.class.php中的代码:
注意, 不要将缓存机制放入doAction()方法中实现, 原因就不用说了吧?
好了, 关于缓存方案这部分就讲到这里了... 学习与使用过程中有任何问题,欢迎发邮件与我共同讨论.
大师兄(teacherli(-at-)gmail.com) 2005-12-19
前几节将PHPSA的一些基本的用法给大家介绍了一下, 这节来看看如果在PHPSA中使用缓存方案. 我们知道, 缓存的级别有两种, 一种为对页面进行缓存, 另一种对数据库提取数据进行缓存, 我们这里主要考虑对页面的缓存方案. 页面缓存基本的原理就是将页面内容缓存到文件, 当第一次缓存后, 在缓存的有效时间内再次请求同一URL时将直接由缓存文件中调出数据, 生成静态页实际就是一种典型的缓存机制, 不过它缓存后会由用户直接请求, 而不再经过PHP进行缓存内容的提取显示. 现在很多的论坛都采用缓存技术来应对大并发用户请求, 它的方案就类似我现在讲的这种方案, 将页面内容先缓存到文件中, 在用户下次进行请求时程序不进行数据库查询而是直接由文件中取出已经缓存的页面内容.
举一个简单的例子: http://abc.com/index.php, index.php文件为首页, 里边包含着大量的新闻性数据, 新闻性的数据又分为很多的子类, 这样, 要想显示给用户完整体的一个首页, index.php中就要对数据库进行多次请求, 这里设定为N次, 而网站又同时并发访问M个用户, 这样, 在单位时间内程序就需要执行M次数据库连接N*M次数据请求, 考虑到首页主要显示一些动态性不高的新闻, 这时我们就可以使用缓存到文件的办法, 在第一次执行index.php时取得index.php显示给用户的完整页面内容, 然后将它写入一个缓存文件index.cache, 在缓存的有效时间内用户再次访问index.php的时候程序使用文件读写方式由index.cache文件中取出所有内容, 然后显示给用户.
PHPSA框架将显示与动作分离, 通过集成的缓存类Cache可以很轻松的完成这种缓存方案, 先来看看Cache类中主要定义的方法:
CODE:
<?php
14.1 getCacheID(): 获取cacheID, 静态调用
14.2 display($cacheID): 显示$cacheID缓存内容, $cacheID为缓存块ID, 静态调用
14.3 fetch($cacheID, $display=false): 获取缓存块内容, $cacheID为缓存ID,$display为是否获取同时进行显示, 静态调用
14.4 isValid($cacheID): 检测$cacheID缓存内容是否有效, 静态调用
14.5 cachePage($cacheID, $contents): 缓存静态页内容, 静态调用
?>
Cache类所有的方法都为静态方法, 程序中我们可以使用Cache::methodName()的方式进行调用.14.1 getCacheID(): 获取cacheID, 静态调用
14.2 display($cacheID): 显示$cacheID缓存内容, $cacheID为缓存块ID, 静态调用
14.3 fetch($cacheID, $display=false): 获取缓存块内容, $cacheID为缓存ID,$display为是否获取同时进行显示, 静态调用
14.4 isValid($cacheID): 检测$cacheID缓存内容是否有效, 静态调用
14.5 cachePage($cacheID, $contents): 缓存静态页内容, 静态调用
?>
缓存主要是对于程序的界面进行缓存, 因而我们要在Action类的doView()方法中实现缓存, 来看defaultAction.class.php中的代码:
CODE:
<?php
/**
* default action
*
* fecollege index page
*
* @author teacherlxj 2005-12-19
*/
class DefaultAction extends Action {
public function DefaultAction($form = null) {
parent::Action($form);
}
//show default page
public function doView() {
/**
* 这里要进行页面缓存要将config.class.php中的CACHE_TIME设置为一个有效的秒数缓存才会生效
*/
ClassLoader::loadUtilsClass("cache");
//cacheID根据URL进行取值, 每个URL对应一个缓存ID
$cacheID = Cache::getCacheID();
if (Cache::isValid($cacheID)){//如果已经缓存且还在缓存时间内
Cache::display($cacheID);
} else { //没有缓存或是已经在缓存时间外
$this->view->setTplDir("./modules/default/views");
$this->view->setTpl("index.html");
ClassLoader::loadModelClass("default");
$defaultBusinessService = new DefaultBusinessService();
//学院信息类新闻 typeID = 1, Config::DEFAULT_NEWS_COUNT在config.class.php中定义
$collegeNewsList = $defaultBusinessService->getNewsList(1, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("collegeNewsList", $collegeNewsList);
unset($collegeNewsList);
//教学教务新闻 typeID = 2
$techNewsList = $defaultBusinessService->getNewsList(2, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("techNewsList", $techNewsList);
unset($techNewsList);
//招生新闻 typeID=3
$recruitNewsList = $defaultBusinessService->getNewsList(3, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("recruitNewsList", $recruitNewsList);
unset($recruitNewsList);
//远程信息新闻 typeID =4
$remoteNewsList = $defaultBusinessService->getNewsList(4, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("remoteNewsList", $remoteNewsList);
unset($remoteNewsList);
//获取当前页面内容, 写入缓存
$contents = $this->view->fetch();
Cache::cachePage($cacheID, $contents);
$this->view->display();
}
}
}
?>
doView()方法中实现的缓存方案. 首先要加载Cache类, 然后使用Cache::getCacheID()获取一个缓存ID号, 缓存ID由URL经过MD5进行加密,然后使用Base64进行编码, 它作为缓存的文件名. 所有缓存文件都被放入Config::APPLICATION_DIR . "/cache"目录, 因此我们在LINUX下使用缓存方案时要注意此目录的存取权限. 接下来使用Cache::isValid($cacheID)来判断缓存是否有效, 这里的有效根据两点进行判断: 1.缓存文件是否存在 2.缓存文件是否还在缓存有效期内, 如果缓存文件有效, 则使用Cache::display($cacheID)方法直接显示缓存文件中的内容, 否则继续执行正常的数据库查询工作. 同样, 按正常的流程, 设定模板目录, 设定模板文件名, 处理模板变量, 在最后, 通过View类的fetch()方法将已经处理完成的模板内容返回,然后将它写入缓存文件, 最后执行模板显示. 流程很简单, 当下次再有用户请求时, Cache::isValid($cacheID)将返回一个true值, 直接由缓存文件中取出页面内容并进行显示./**
* default action
*
* fecollege index page
*
* @author teacherlxj 2005-12-19
*/
class DefaultAction extends Action {
public function DefaultAction($form = null) {
parent::Action($form);
}
//show default page
public function doView() {
/**
* 这里要进行页面缓存要将config.class.php中的CACHE_TIME设置为一个有效的秒数缓存才会生效
*/
ClassLoader::loadUtilsClass("cache");
//cacheID根据URL进行取值, 每个URL对应一个缓存ID
$cacheID = Cache::getCacheID();
if (Cache::isValid($cacheID)){//如果已经缓存且还在缓存时间内
Cache::display($cacheID);
} else { //没有缓存或是已经在缓存时间外
$this->view->setTplDir("./modules/default/views");
$this->view->setTpl("index.html");
ClassLoader::loadModelClass("default");
$defaultBusinessService = new DefaultBusinessService();
//学院信息类新闻 typeID = 1, Config::DEFAULT_NEWS_COUNT在config.class.php中定义
$collegeNewsList = $defaultBusinessService->getNewsList(1, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("collegeNewsList", $collegeNewsList);
unset($collegeNewsList);
//教学教务新闻 typeID = 2
$techNewsList = $defaultBusinessService->getNewsList(2, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("techNewsList", $techNewsList);
unset($techNewsList);
//招生新闻 typeID=3
$recruitNewsList = $defaultBusinessService->getNewsList(3, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("recruitNewsList", $recruitNewsList);
unset($recruitNewsList);
//远程信息新闻 typeID =4
$remoteNewsList = $defaultBusinessService->getNewsList(4, Config::DEFAULT_NEWS_COUNT);
$this->view->assign("remoteNewsList", $remoteNewsList);
unset($remoteNewsList);
//获取当前页面内容, 写入缓存
$contents = $this->view->fetch();
Cache::cachePage($cacheID, $contents);
$this->view->display();
}
}
}
?>
注意, 不要将缓存机制放入doAction()方法中实现, 原因就不用说了吧?
好了, 关于缓存方案这部分就讲到这里了... 学习与使用过程中有任何问题,欢迎发邮件与我共同讨论.