PHPCMS的文本缓存实现
CODE:
1
<?php
2
defined('IN_PHPCMS') or exit('Access Denied');
3
/**
4
这个文件里面全是有关生成文本缓存的函数。文本缓存是个好东西。一般的项目,我们用不着内存缓存 : memcached ,文本搞定。
5
原理是这样的: 我们在后台是不是可以设置很多有关网站的参数。而这些参数很多都是固定的。就不变化的。都存到咱的数据库上。而我们程序那里呢
6
每次都要访问数据库读出参数来进行我们程序中的操作。首先数据库查询是个很耗硬盘IO资源的一个东西,所以文本缓存刚好能减轻数据库那边的承重。
7
我们在程序开始就把数据库里面的配置都转化为数组 等 放到 php文件里面。这样我们可以直接访问php文件而不用每次都访问数据库了。 php文本缓存其实成了
8
我们程序和数据库的一个中间件。 所以我们自己写自己的文本缓存的时候其实要实现的很简单: 读数据库 -> 写到PHP文件 -> 程序中include
9
来吧。开始文本缓存学习
10
*/
11
function cache_all() //生成所有缓存的总操作函数
12
{
13
cache_table(); //生成所有的数据库表名,表名是根据数据库里面当前的表明而生成。请看这个函数的详细分析
14
require_once PHPCMS_CACHEDIR.'table.php'; //包含表常量
15
cache_common();
16
cache_member_group();
17
$modules = cache_module();
18
$channelids = cache_channel(0);
19
$keyids = array_merge($modules, $channelids);
20
foreach($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
}
31
cache_type(0);
32
return TRUE;
33
}
34
function cache_common()
35
{
36
global $db;
37
$query = $db->query("SELECT module,name,iscore,iscopy,isshare,moduledir,moduledomain FROM ".TABLE_MODULE." WHERE disabled=0"); //查询所有能用的模块
38
while($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,
50
style,islink,linkurl,cat_html_urlruleid,item_html_urlruleid,special_html_urlruleid,
51
cat_php_urlruleid,item_php_urlruleid,special_php_urlruleid FROM ".TABLE_CHANNEL." WHERE disabled=0 ORDER by listorder"); //罗列能用的频道列表
52
while($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;
73
cache_write('common.php', $CACHE); //开始把$CACHE 数组写到 common.php 这个文本缓存里。大家可以自己去打开这个文件看下内容。一切了然
74
return $CACHE;
75
}
76
function cache_update($action='')//更新文本缓存。最好在后台操作使用。因为PHP的文件flock 文件锁在某些平台使用不是很好。会出现多用户同写一个文件从而破坏缓存文件
77
{
78
global $db;
79
$data=array();
80
switch($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
}
100
cache_write('cache_'.$action.'.php', $data);
101
return $data;
102
}
103
function cache_table()
104
{
105
global $db,$CONFIG;
106
$query = $db->query("SHOW TABLES FROM `".$CONFIG['dbname']."`");
107
/**
108
显示数据库里面的所有表名
109
*/
110
while($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() 函数 主要是为了清除数据库大的查询而占用的内存。还是有必要的哦
120
if(!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
}
129
cache_write('table.php', $data , 'constant'); //很多朋友说找不到phpcms 表常量在那里定义的。就是在这里。
130
/**
131
cache_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
*/
167
return $data;
168
}
169
/**
170
phpcms 的所有数据库表名 都用根据数据库当前的表名来用常量来进行定义。我认为这样设计不是很好。不够灵活:比如如果我们更改数据库的一个表名的话。
171
那么会出现找不到表的错误信息。而且想要修复还很麻烦。就是说不能随便更改表名了。不推荐大家这样写。我们可以把表名都定义在一个PHP文件里面。这样我们以后
172
要改某个表名,就很方便了。
173
*/
<?php 2
defined('IN_PHPCMS') or exit('Access Denied');3
/**4
这个文件里面全是有关生成文本缓存的函数。文本缓存是个好东西。一般的项目,我们用不着内存缓存 : memcached ,文本搞定。5
原理是这样的: 我们在后台是不是可以设置很多有关网站的参数。而这些参数很多都是固定的。就不变化的。都存到咱的数据库上。而我们程序那里呢6
每次都要访问数据库读出参数来进行我们程序中的操作。首先数据库查询是个很耗硬盘IO资源的一个东西,所以文本缓存刚好能减轻数据库那边的承重。7
我们在程序开始就把数据库里面的配置都转化为数组 等 放到 php文件里面。这样我们可以直接访问php文件而不用每次都访问数据库了。 php文本缓存其实成了8
我们程序和数据库的一个中间件。 所以我们自己写自己的文本缓存的时候其实要实现的很简单: 读数据库 -> 写到PHP文件 -> 程序中include 9
来吧。开始文本缓存学习 10
*/11
function cache_all() //生成所有缓存的总操作函数12
{13
cache_table(); //生成所有的数据库表名,表名是根据数据库里面当前的表明而生成。请看这个函数的详细分析14
require_once PHPCMS_CACHEDIR.'table.php'; //包含表常量15
cache_common();16
cache_member_group();17
$modules = cache_module();18
$channelids = cache_channel(0);19
$keyids = array_merge($modules, $channelids);20
foreach($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
} 31
cache_type(0);32
return TRUE;33
}34
function cache_common()35
{36
global $db;37
$query = $db->query("SELECT module,name,iscore,iscopy,isshare,moduledir,moduledomain FROM ".TABLE_MODULE." WHERE disabled=0"); //查询所有能用的模块38
while($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,50
style,islink,linkurl,cat_html_urlruleid,item_html_urlruleid,special_html_urlruleid,51
cat_php_urlruleid,item_php_urlruleid,special_php_urlruleid FROM ".TABLE_CHANNEL." WHERE disabled=0 ORDER by listorder"); //罗列能用的频道列表52
while($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;73
cache_write('common.php', $CACHE); //开始把$CACHE 数组写到 common.php 这个文本缓存里。大家可以自己去打开这个文件看下内容。一切了然74
return $CACHE;75
}76
function cache_update($action='')//更新文本缓存。最好在后台操作使用。因为PHP的文件flock 文件锁在某些平台使用不是很好。会出现多用户同写一个文件从而破坏缓存文件77
{78
global $db;79
$data=array();80
switch($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
}100
cache_write('cache_'.$action.'.php', $data);101
return $data;102
}103
function cache_table()104
{105
global $db,$CONFIG;106
$query = $db->query("SHOW TABLES FROM `".$CONFIG['dbname']."`");107
/**108
显示数据库里面的所有表名109
*/110
while($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() 函数 主要是为了清除数据库大的查询而占用的内存。还是有必要的哦120
if(!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
}129
cache_write('table.php', $data , 'constant'); //很多朋友说找不到phpcms 表常量在那里定义的。就是在这里。130
/**131
cache_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
*/167
return $data;168
}169
/**170
phpcms 的所有数据库表名 都用根据数据库当前的表名来用常量来进行定义。我认为这样设计不是很好。不够灵活:比如如果我们更改数据库的一个表名的话。171
那么会出现找不到表的错误信息。而且想要修复还很麻烦。就是说不能随便更改表名了。不推荐大家这样写。我们可以把表名都定义在一个PHP文件里面。这样我们以后172
要改某个表名,就很方便了。173
*/
浙公网安备 33010602011771号