igaofen

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

PHPCMS的文本缓存实现
CODE:

  1<?php 
  2defined('IN_PHPCMS') or exit('Access Denied');
  3/**
  4这个文件里面全是有关生成文本缓存的函数。文本缓存是个好东西。一般的项目,我们用不着内存缓存 : memcached  ,文本搞定。
  5原理是这样的: 我们在后台是不是可以设置很多有关网站的参数。而这些参数很多都是固定的。就不变化的。都存到咱的数据库上。而我们程序那里呢
  6每次都要访问数据库读出参数来进行我们程序中的操作。首先数据库查询是个很耗硬盘IO资源的一个东西,所以文本缓存刚好能减轻数据库那边的承重。
  7我们在程序开始就把数据库里面的配置都转化为数组 等  放到  php文件里面。这样我们可以直接访问php文件而不用每次都访问数据库了。  php文本缓存其实成了
  8我们程序和数据库的一个中间件。 所以我们自己写自己的文本缓存的时候其实要实现的很简单:  读数据库  ->  写到PHP文件 ->  程序中include 
  9来吧。开始文本缓存学习 
 10*/
 11function cache_all()  //生成所有缓存的总操作函数
 12{
 13cache_table(); //生成所有的数据库表名,表名是根据数据库里面当前的表明而生成。请看这个函数的详细分析
 14require_once PHPCMS_CACHEDIR.'table.php'//包含表常量
 15cache_common();
 16cache_member_group();
 17$modules = cache_module();
 18$channelids = cache_channel(0);
 19$keyids = array_merge($modules, $channelids);
 20foreach($keyids as $keyid)
 21{
 22  $catids = cache_categorys($keyid);
 23  if(is_array($catids))
 24  {
 25   foreach($catids as $catid)
 26   {
 27    cache_category($catid);
 28   }
 29  }
 30
 31cache_type(0);
 32return TRUE;
 33}
 34function cache_common()
 35{
 36global $db;
 37$query = $db->query("SELECT module,name,iscore,iscopy,isshare,moduledir,moduledomain FROM ".TABLE_MODULE." WHERE disabled=0"); //查询所有能用的模块
 38while($r = $db->fetch_array($query))
 39{
 40  $r['linkurl'= ''
 41  if($r['module'!= 'phpcms' && $r['iscopy'== 0$r['linkurl'= linkurl($r['moduledomain'? dir_path($r['moduledomain']) : $r['moduledir'].'/');
 42  //如果模块存在目录的就取它目录地址
 43  unset($r['moduledomain']);
 44  $key = $r['module'];
 45  $data[$key= $r
 46}
 47$CACHE['module'= $data//存到缓存数组,等一下一起把 $CACHE 数组写到文本里去
 48$data = array();
 49$query = $db->query("SELECT channelid,module,channelname,channeldir,channeldomain,channelpic,introduce,
 50style,islink,linkurl,cat_html_urlruleid,item_html_urlruleid,special_html_urlruleid,
 51cat_php_urlruleid,item_php_urlruleid,special_php_urlruleid FROM ".TABLE_CHANNEL." WHERE disabled=0 ORDER by listorder"); //罗列能用的频道列表
 52while($r = $db->fetch_array($query))
 53{
 54  $r['linkurl'= linkurl($r['linkurl']);
 55  $key = $r['channelid'];
 56  $data[$key= $r;
 57}
 58$CACHE['channel'= $data//存到缓存数组
 59$data = array();
 60    $r = $db->get_one("SELECT setting FROM ".TABLE_MODULE." WHERE module='phpcms'"); 
 61$CACHE['phpcms'= unserialize($r['setting']);
 62//查询 phpcms这个模块的设置信息,大家可以看下数据库这个表内容。setting 字段里面的信息是经过serialize 函数窜行化的。
 63//所以取出的内容要unserialize 反窜行.我是挺喜欢使用serialize 函数的。他可以实现把一个数组存到数据库或把一个对象存到数据库。或是拿来GET传递都行。
 64//太强了。大家可以试用下。可能你项目某个地方需要用到哦。
 65$fields = array();
 66$result = $db->query("SELECT * FROM ".TABLE_FIELD." ORDER BY fieldid"); //下栽模块的信息,请自己看下这个表的数据就明白
 67    while($r = $db->fetch_array($result))
 68{
 69  $tablename = $r['tablename'];
 70  $fields[$tablename.= ','.$r['name'];
 71}
 72$CACHE['field'= $fields;
 73cache_write('common.php', $CACHE); //开始把$CACHE 数组写到 common.php 这个文本缓存里。大家可以自己去打开这个文件看下内容。一切了然
 74    return $CACHE;
 75}
 76function cache_update($action='')//更新文本缓存。最好在后台操作使用。因为PHP的文件flock 文件锁在某些平台使用不是很好。会出现多用户同写一个文件从而破坏缓存文件
 77{
 78global $db;
 79$data=array();
 80switch($action)
 81{
 82  case 'keylink';
 83   $query=$db->query("SELECT linktext,linkurl FROM ".TABLE_KEYLINK." where passed=1");
 84   while($r=$db->fetch_array($query)){
 85      $data[]=$r;
 86   }
 87  break;
 88  case 'reword';
 89   $query = $db->query("SELECT word,replacement FROM ".TABLE_REWORD." where passed=1");
 90   while($r = $db->fetch_array($query))
 91   {
 92    $data[]=$r;
 93   }
 94  break;
 95  default:
 96   $actions = array('keylink','reword');
 97   array_map('cache_update', $actions);
 98   return TRUE;
 99}
100cache_write('cache_'.$action.'.php', $data);
101return $data;
102}
103function cache_table()
104{
105global $db,$CONFIG;
106$query = $db->query("SHOW TABLES FROM `".$CONFIG['dbname']."`");
107/**
108显示数据库里面的所有表名
109*/
110while($r = $db->fetch_row($query))
111{
112  $table = $r[0];
113  if(preg_match("/^".$CONFIG['tablepre']."/i", $table)) //寻找表前缀等于 $CONFIG['tablepre'] (在config.inc.php里设置) @@表前缀还有这个作用 嘿嘿
114  {
115   $tablename = str_replace($CONFIG['tablepre'], 'table_', $table);
116   $data[$tablename= $table;    //  $data['table_xx'] = xx; 形式   只能意会下了 
117  }
118}
119$db->free_result($query);  //$db->free_result()  这个类方法其实是掉用了函数:mysql_free_result() 函数 主要是为了清除数据库大的查询而占用的内存。还是有必要的哦
120if(!is_dir(PHPCMS_CACHEDIR)) // 常量 PHPCMS_CACHEDIR 在 common.inc.php 里面定义的。大家不记得了去看看吧。是存放phpcms 缓存目录的路径,这里意思是:如果缓存目录不存在
121{
122  dir_create(PHPCMS_CACHEDIR); //如果缓存目录不存在那么就创建
123  dir_create($CONFIG['templatescachedir']); //创建编译后的PHP模板目录,有关phpcms模板引擎编写。在下一章合适就开讲
124  /**
125  dir_create() 函数为创建 目录函数。PHPCMS自己封装的,刚看了下。phpcms 挺强。这个函数还可以通过ftp 来创建目录。这样就可以解决一些 开启了安全模式下的服务器对于创建目录等出现的问题
126  因为涉及到PHP FTP 知识。所以打算讲解到下面再说。
127  */
128}
129cache_write('table.php', $data , 'constant'); //很多朋友说找不到phpcms 表常量在那里定义的。就是在这里。
130/**
131cache_write() 函数在global.func.php里面定义的。是把 已经从数据库取出来的数组信息写到 PHP文本上去。@@文本缓存关键的一步  废话少说上菜:
132  function cache_write($file, $string, $type = 'array')
133  {
134   if(is_array($string)) //检测 $string 内容是字符窜的呢还是数组的,是数组的那就继续 ..
135   {
136    $type = strtolower($type);  
137    if($type == 'array')//然后再判断这个函数的模式标致 ,是否为数组模式,默认为数组模式
138    {
139     $string = "<?php"n return ".var_export($string,TRUE).";"n?>"; 
140     //这个太关键了。因为我们把数据库的信息写到文本上去的时候。是以符合PHP语法的格式写进去的。为什么呢?@@ 十分废话,因为如果不是以PHP格式写到文件里面去
141     那么这个PHP文件怎么能给我们include 进程序运行调用呢? 呵呵。 知道这一点就真的明白文本缓存的实现了。忒简单。 这里使用了个小技巧:使用了 var_export() 函数
142     这个函数会返回一个变量的字符窜形式。这个函数太有帮助了。如果没有这个函数,我们还要自己想办法实现呢。自己写一次文本缓存就明白了。会碰到这个问题的。 '"n' 这个是
143     文本文件的换行。初学者 别把<br> 和 '"n' 搞混罗。 一个是html 的 一个是文本文件的
144    }
145    elseif($type == 'constant') //以内容形式
146    {
147     $data='';
148     foreach($string as $key => $value) $data .= "define('".strtoupper($key)."','".addslashes($value)."');"n";
149     $string = "<?php"n".$data.""n?>";
150     如果以内容形式的话。就不是写数组到文本里面了。而是把内容都定义成常量。 
151    }
152   }
153   $strlen = file_put_contents(PHPCMS_CACHEDIR.$file, $string);//file_put_contents()函数 是PHP5才支持的 效率最好。建议使用
154   chmod(PHPCMS_CACHEDIR.$file, 0777); 设置目录 为可读可写可执行
155   return $strlen; //返回写到文本的字节数
156  }
157  
158  再说多一个读 缓存文件的操作函数  :上菜
159  function cache_read($file, $mode = 'i')
160   {
161    $cachefile = PHPCMS_CACHEDIR.$file;
162    if(!file_exists($cachefile)) return array();
163    return $mode == 'i' ? include $cachefile : file_get_contents($cachefile);
164   }
165   读缓存其实就是 include php缓存文件。 讲完走人
166*/
167return $data;
168}
169/**
170phpcms 的所有数据库表名 都用根据数据库当前的表名来用常量来进行定义。我认为这样设计不是很好。不够灵活:比如如果我们更改数据库的一个表名的话。
171那么会出现找不到表的错误信息。而且想要修复还很麻烦。就是说不能随便更改表名了。不推荐大家这样写。我们可以把表名都定义在一个PHP文件里面。这样我们以后
172要改某个表名,就很方便了。
173*/
posted on 2009-09-07 00:25  igaofen  阅读(458)  评论(0编辑  收藏  举报