PHPCMS整站源码分析

/**

代码分析版权所有:逆雪寒

*/

require'./include/common.inc.php';

/**

看 common.inc.php 核心启动文件我们已经讲解完了。应该都明白了吧

*/

if($PHPCMS['ishtml']==1&&

file_exists(PHPCMS_ROOT.'/'.$PHPCMS['index'].'.'.$PHPCMS[ 'fileext']))

{

header('location:'.$PHPCMS['index'].'.'.$PHPCMS['fileext' ]);

exit;

}

/**

phpcms 允许在后台生静态和使用静态,这里就是先判断

$PHPCMS['ishtml'](从文本缓存弄过来的。应该知道了吧)是否为1 就是开启了。和这个静态的html文件是否存在。

*/

$channels=array();

$channels['article']=$channels['down']=

$channels['picture']=$channels['info']=array();

foreach($CHANNEL as$v)

{

$module=$v['module'];

if($v['islink']==0&&$MODULE[$module]['iscopy']==1) $channels[$module][$v['channelid']]=$v;

}

//获取频道模块的信息。都是从缓存中取的

$head['title']=$PHPCMS['seo_title'];

$head['keywords']=$PHPCMS['seo_keywords'];

$head['description']=$PHPCMS['seo_description'];

// 这个是网页的SEO (title,keywords,description)信息。这个写好了。网络蜘蛛会找你哦。

include template('phpcms','index');

// template() 函数是模板函数。这个就是这章的主题。往下会讲模板引擎的制作,大家都看到include 了吧。它的参数是文件地址。那么就可以想到template()函数其实就是

// 模板编译后的PHP文件地址。

phpcache();

/**

这个函数厉害了。用来自动生缓存页的(这个是页面缓存和数据库信息的文本缓

存不是一会事),页面缓存,就是把你所看的页自动生成 XX.html 静态页。请注意前面代码。是不是有个 header()跳转到静态页呀。

那静态页那里来的?就是给这个函数弄出来的。自动静态化了其实。@@是不是很简单呢。上菜先:

function phpcache($is_js = 0)

{

global $CONFIG,$cachefiledir,$cachefile;

if(!$is_js && $CONFIG['phpcache'] != '2') return FALSE; $contents = ob_get_clean();

if($is_js) $contents = strip_js($contents);

if($CONFIG['phpcache'] == '2' && $cachefiledir && $cachefile) {

dir_create($cachefiledir);

file_put_contents($cachefile, $contents);

@chmod($cachefile, 0777);

}

header('Expires: Mon, 26 Jul 2000 05:00:00 GMT'); 告诉浏览器此页面的过期时间(用格林威治时间表示),只要是已经过去的日期即可

header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 告诉服务器本页最后修改日期。目的就是强迫浏览器获取最新资料

header('Cache-Control: no-cache, must-revalidate'); 这句session_cache_limiter('private') 作用差不多。就是用户点击后退不会出现警告页。十分有用哦。大家别忘了

header('Pragma: no-cache'); 不缓存当前页。其实和前一句一样意思,这句不过是为了兼容http1.0协议。

echo $contents; //输出内容。

}

首先判断。文件当前文件不是JS问文件和后台打开了页面缓存静态化,。然后

使用了OB读写缓冲区系列函数来操作缓冲区。

ob_get_clean() 函数。十分有用。一般我们做整站静态化也是利用OB系列

函数来实现。

这个函数就是获取当前缓冲区的HTML内容。然后把将要输出的缓冲区内容清除掉。网页先是一点点读到浏览器的缓冲区。当缓冲区满了以后才会放出来。所以

我们

可以用OB系列函数在缓冲区没有输出之前截取内容来做我们要做的过滤等动作。(dz的伪静态有部分就这样实现的。把缓冲区中的所有超级连接地址更改成: thread-46695-1-3.html 形式。然后apache 那边再用.hataccess 来做

判断跳转) 这里也是。我们获取将要输出的内容以后调用 strip_js() 这个

函数来过滤HTML内容。因为比较简单继续上菜:

function strip_js($string, $js = 1)

{

$string =

str_replace(array("\n","\r","\""),array('','',"[url=]\\\" "),$string[/url]);

return $js==1 ? "document.write(\"".$string."\");\n" : $string;

}

主要是来过滤内容里面的 \n 换行、\r 换页符和 '\' 具体请百度:制表符

继续我们上个函数strip_js过滤完内容后。在使用 file_put_contents() 函数把内容写到文件里面去。也就是那个 HTML静态页,恩完成了。当前页的

静态页已经存在了。

但好象不对是吧。因为你刚用了 ob_get_clean() 函数。截取内容后清空了输出的内容。那就是浏览器成了空白页了。所以我们要手动的来 echo 输出内容给客户看。echo 前呢

还有些东西要做就是 header 几个http协议头过去注释已经给出。详细的百度:http协议,会有详细的参数说明。其主要目的是:强制用户每次访问这个页面时获取最新资料,而不是使用存在客户端的缓存。

*/

?>

关于phpcms cache原理,探讨

phpcms二次开发QQ:267014881 长沙php 交流

软件版本:phpcms2008 Linux王国http://m.wendangku.net/doc/c41588264b35eefdc8d333c2.html转载请注明原处

a.页面缓存,在后台网站配置-》性能优化中,配置了启用PHP页面缓存

if(CACHE_PAGE && !defined('IN_ADMIN')) cache_page_start(); //看是否调用页面缓存

global.func.php 有如下函数

function cache_page_start()

{

define('CACHE_PAGE_ID', md5(RELATE_URL));

//定义cache文件的id,其中RELATE_URL在,common.inc.php 中//define('RELATE_URL', isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : SCRIPT_NAME.(QUERY_STRING ? '?'.QUERY_STRING : PATH_INFO));

//把本身的url+它get后的参数,两者md5加密,用来查找和生成cache-id

define('CACHE_PAGE_DIR', CACHE_PAGE_PATH.substr(CACHE_PAGE_ID, 0, 2).'/');

////页面缓存配置(config.inc.php)

//define('CACHE_PAGE', 0); //是否开启PHP页面自动缓存功能

//define('CACHE_PAGE_PATH', PHPCMS_ROOT.'data/cache_page/'); //缓存存储路径

//define('CACHE_PAGE_TTL', 3600); //秒,缓存默认生命周期

//define('CACHE_PAGE_INDEX_TTL', 300); //秒,缓存默认生命周期

//define('CACHE_PAGE_CATEGORY_TTL', 600); //秒,缓存默认生命周期

//define('CACHE_PAGE_LIST_TTL', 900); //秒,缓存默认生命周期

/define('CACHE_PAGE_CONTENT_TTL', 14400); //秒,缓存默认生命周期

//PHPCMS_ROOT.'data/cache_page/+cacheid的前三位

define('CACHE_PAGE_FILE', CACHE_PAGE_DIR.CACHE_PAGE_ID.'.html'); //加载cache文件

$contents = @file_get_contents(CACHE_PAGE_FILE);

if($contents && intval(substr($contents, 15, 25)) > TIME) //判断是否过期,如果没有,就输出文件29个字

符以后的所有文件

{

echo substr($contents, 29);

exit;

}

return true;

}

//生成cahe文件

function cache_page($ttl = CACHE_PAGE_TTL, $isjs = 0)

{

if($ttl == 0 || !defined('CACHE_PAGE_FILE')) return false;

$contents = ob_get_contents();

if($isjs) $contents = format_js($contents); //读入数据,格式化js

dir_create(CACHE_PAGE_DIR);

$contents = "\n".$contents; //加上时间和超时时间,以到后面取的时候好

对比

file_put_contents(CACHE_PAGE_FILE, $contents); //写入文件

@chmod(CACHE_PAGE_FILE, 0777);

}

//清除所有的cache文件,也是data/cache_page下的文件

function cache_page_clear()

{

@set_time_limit(600);

$dirs = glob(CACHE_PAGE_PATH.'*');

foreach($dirs as $dir)

{

$files = glob($dir.'/*');

foreach($files as $file)

{

@unlink($file);

}

@rmdir($dir);

}

}

//统计cache的更新时间和并写到数据库,比如更新时间,更新了多少次

//$M = $TEMP = array();

function cache_count($sql)

{

global $db, $TEMP;

$id = md5($sql);

if(!isset($TEMP['count'][$id]))

{

if(CACHE_COUNT_TTL)

{

$r = $db->get_one("SELECT `count`,`updatetime` FROM `".DB_PRE."cache_count` WHERE

`id`='$id'");

if(!$r || $r['updatetime'] < TIME - CACHE_COUNT_TTL)

{

$r = $db->get_one($sql);

$TEMP['count'][$id] = $r['count'];

$db->query("REPLACE INTO `".DB_PRE."cache_count`(`id`, `count`, `updatetime`) VALUES('$id',

'".$r['count']."', '".TIME."')");

}

}

else

{

$r = $db->get_one($sql);

}

$TEMP['count'][$id] = $r['count'];

}

return $TEMP['count'][$id];

}

//用户信息的cache文件,现在我还不知道什么意思

function cache_member()

{

global $db;

$status = $db->table_status(DB_PRE.'member_cache');

if($status['Rows'] == 0)

{

@set_time_limit(600);

$db->query("INSERT INTO `".DB_PRE."member_cache` SELECT * FROM `".DB_PRE."member`");

return true;

}

return false;

}

//------------------------

//以上这些是页面cache的部分函数,其实也就是文本cache的一种方式,不过这个要在后台设置开启才

//phpcms 2008默认是不开启,如上开关的,

//下面来介绍phpcms2008默认的文件cahce 模式

b.文件cahce

//在global.ini.php中发现如下函数

//它的cache文件的目录是daba/cahce/下的很多x.php的文件,这些文件你可以打开看一下发现是一些生

成好的数组文件

//平时在后台,点更新首页,其实也就是更新了这些变量,其中用到的var_export()这个php默认函数,大

家可以看一下手册

function cache_read($file, $path = '', $iscachevar = 0)

{

if(!$path) $path = CACHE_PATH;

$cachefile = $path.$file;

if($iscachevar) //判断是否cache变量

{

global $TEMP; //temp是全局性的临时变量,记录一些用户信息及配置信息,在commom.ini.php中有

定义,

$key = 'cache_'.substr($file, 0, -4); //去掉文件的后四位作为key,这个后四位暂时我也不

明白,等后面分析

return isset($TEMP[$key]) ? $TEMP[$key] : $TEMP[$key] = @include $cachefile;

}

return @include $cachefile;

}

//生成cache文件

function cache_write($file, $array, $path = '')

{

if(!is_array($array)) return false;

$array = "";

$cachefile = ($path ? $path : CACHE_PATH).$file;

$strlen = file_put_contents($cachefile, $array);

@chmod($cachefile, 0777);

return $strlen;

}

//删除cache文件

function cache_delete($file, $path = '')

{

$cachefile = ($path ? $path : CACHE_PATH).$file;

return @unlink($cachefile);

}

这只是文本cache的部分东西

全部函数在cache.func.php

介强一下这个函数,大至过程就是通过数据库调用数据,生成变量,变量写入文件,文件在调用时被引入到

模板文件

function cache_all()

{

@set_time_limit(600);

cache_common();

cache_module();

cache_model();

cache_category();

cache_area();

cache_type();

cache_member_group();

cache_role();

cache_author();

cache_keyword();

cache_copyfrom();

cache_pos();

cache_status();

cache_workflow();

tags_update();

return TRUE;

}

/**

mysql数据库类。写得比较简单。也没什么好说的。大家自己看下理解下。

然后就可以跳过了。

*/

defined('IN_PHPCMS') or exit('Access Denied');

/**

这个东西是不是很熟呀。对了。在上一章已经讲过了。也已经在上一章的common.inc.php 启动文件里面定义了 IN_PHPCMS 所以在以下的PHP文件里都检测下是否是人为”跳墙“进来的。是就中断

*/

/**

* Mysql 数据库类,支持Cache功能

*/

class db_mysql

{

/**

* MySQL 连接标识

* @var resource

*/

var $connid;

/**

* 整型变量用来计算被执行的sql语句数量

* @var int

*/

var $querynum = 0;

/**

* 数据库连接,返回数据库连接标识符

* @param string 数据库服务器主机

* @param string 数据库服务器帐号

* @param string 数据库服务器密码

* @param string 数据库名

* @param bool 是否保持持续连接,1为持续连接,0为非持续连接

* @return link_identifier

*/

function connect($dbhost, $dbuser, $dbpw, $dbname, $pconnect = 0)

{

global $CONFIG;

$func = $pconnect == 1 ? 'mysql_pconnect' : 'mysql_connect';

/**

mysql_pconnect() 为常连接。它和mysql_connect 的区别是前者在多进程的WEB服务器上效率比较好。但也有瑕疵就是在有关事务和数据表锁方面。详情请查看自己的手册。

*/

if(!$this->connid = @$func($dbhost, $dbuser, $dbpw))

{

$this->halt('Can not connect to MySQL server');

}

// 当mysql版本为4.1以上时,启用数据库字符集设置

if($this->version() > '4.1' && $CONFIG['dbcharset'])

{

mysql_query("SET NAMES '".$CONFIG['dbcharset']."'" , $this->connid);

}

// 当mysql版本为5.0以上时,设置sql mode,mysql5数据库带了字符集模式。设置下就好

if($this->version() > '5.0')

{

mysql_query("SET sql_mode=''" , $this->connid);

}

if($dbname)

{

if([email=!@mysql_select_db($dbname]!@mysql_select_db($dbname[/email] , $this->connid)) {

$this->halt('Cannot use database '.$dbname);

}

}

return $this->connid;

}

/**

* 选择数据库

* @param string 数据库名

*/

function select_db($dbname)

{

return mysql_select_db($dbname , $this->connid);

}

/**

* 执行sql语句

* @param string sql语句

* @param string 默认为空,可选值为 CACHE UNBUFFERED

* @param int Cache以秒为单位的生命周期

* @return resource

*/

function query($sql , $type = '' , $expires = 3600, $dbname = '')

{

$func = $type == 'UNBUFFERED' ? 'mysql_unbuffered_query' : 'mysql_query';

/**

mysql_unbuffered_query 效率更好。节省内存看手册

*/

if(!($query = $func($sql , $this->connid)) && $type != 'SILENT')

{

$this->halt('MySQL Query Error', $sql);

}

$this->querynum++;

return $query;

}

/**

* 执行sql语句,只得到一条记录

* @param string sql语句

* @param string 默认为空,可选值为 CACHE UNBUFFERED

* @param int Cache以秒为单位的生命周期

* @return array

*/

function get_one($sql, $type = '', $expires = 3600, $dbname = '')

{

$query = $this->query($sql, $type, $expires, $dbname);

$rs = $this->fetch_array($query);

$this->free_result($query);

return $rs ;

}

/**

* 从结果集中取得一行作为关联数组

* @param resource 数据库查询结果资源

* @param string 定义返回类型

* @return array

*/

function fetch_array($query, $result_type = MYSQL_ASSOC)

{

return mysql_fetch_array($query, $result_type); }

/**

* 取得前一次 MySQL 操作所影响的记录行数

* @return int

*/

function affected_rows()

{

return mysql_affected_rows($this->connid);

}

/**

* 取得结果集中行的数目

* @return int

*/

function num_rows($query)

{

return mysql_num_rows($query);

}

/**

* 返回结果集中字段的数目

* @return int

*/

function num_fields($query)

{

return mysql_num_fields($query);

}

/**

* @return array

*/

function result($query, $row)

{

return @mysql_result($query, $row);

}

function free_result($query)

{

return mysql_free_result($query);

}

/**

* 取得上一步 INSERT 操作产生的 ID

* @return int

*/

function insert_id()

{

return mysql_insert_id($this->connid);

/**

* @return array

*/

function fetch_row($query)

{

return mysql_fetch_row($query);

}

/**

* @return string

*/

function version()

{

return mysql_get_server_info($this->connid);

}

function close()

{

return mysql_close($this->connid);

}

/**

* @return string

*/

function error()

{

return @mysql_error($this->connid);

}

/**

* @return int

*/

function errno()

{

return intval(@mysql_errno($this->connid)) ;

}

/**

mysql_errno() 函数也挺好使的哦。自己试下

*/

/**

* 显示mysql错误信息

*/

function halt($message = '', $sql = '')

{

exit("MySQL Query:$sql
MySQL Error:".$this->error()."
MySQL Errno:".$this->errno ()."
Message:$message");

}

?>

PHPCMS的文本缓存实现:

复制PHP内容到剪贴板

PHP代码:

defined('IN_PHPCMS') or exit('Access Denied');

/**

这个文件里面全是有关生成文本缓存的函数。文本缓存是个好东西。一般的项目,我们用不着内存缓

存: memcached ,文本搞定。

原理是这样的:我们在后台是不是可以设置很多有关网站的参数。而这些参数很多都是固定的。就不变化的。都存到咱的数据库上。而我们程序那里呢

每次都要访问数据库读出参数来进行我们程序中的操作。首先数据库查询是个很耗硬盘IO资源的一个东西,所以文本缓存刚好能减轻数据库那边的承重。

我们在程序开始就把数据库里面的配置都转化为数组等放到 php文件里面。这样我们可以直接访问php文件而不用每次都访问数据库了。 php文本缓存其实成了

我们程序和数据库的一个中间件。所以我们自己写自己的文本缓存的时候其实要实现的很简单:读数据库 -> 写到PHP文件 -> 程序中include

来吧。开始文本缓存学习

*/

function cache_all() //生成所有缓存的总操作函数

{

cache_table(); //生成所有的数据库表名,表名是根据数据库里面当前的表明而生成。请看这个函数的详细分析

require_once PHPCMS_CACHEDIR.'table.php'; //包含表常量

cache_common();

cache_member_group();

$modules = cache_module();

$channelids = cache_channel(0);

$keyids = array_merge($modules, $channelids);

foreach($keyids as $keyid)

{

$catids = cache_categorys($keyid);

if(is_array($catids))

{

foreach($catids as $catid)

{

cache_category($catid);

}

}

}

cache_type(0);

return TRUE;

}

function cache_common()

{

global $db;

$query = $db->query("SELECT module,name,iscore,iscopy,isshare,moduledir,moduledomain FROM ". TABLE_MODULE." WHERE disabled=0"); //查询所有能用的模块

while($r = $db->fetch_array($query))

{

$r['linkurl'] = '';

if($r['module'] != 'phpcms' && $r['iscopy'] == 0) $r['linkurl'] = linkurl($r['moduledomain '] ? dir_path($r['moduledomain']) : $r['moduledir'].'/');

//如果模块存在目录的就取它目录地址

unset($r['moduledomain']);

$key = $r['module'];

$data[$key] = $r;

}

$CACHE['module'] = $data; //存到缓存数组,等一下一起把 $CACHE 数组写到文本里去

$data = array();

$query = $db->query("SELECT channelid,module,channelname,channeldir,channeldomain,channelpic ,introduce,style,islink,linkurl,cat_html_urlruleid,item_html_urlruleid,special_html_urlrulei d,cat_php_urlruleid,item_php_urlruleid,special_php_urlruleid FROM ".TABLE_CHANNEL." WHERE di sabled=0 ORDER by listorder"); //罗列能用的频道列表

while($r = $db->fetch_array($query))

{

$r['linkurl'] = linkurl($r['linkurl']);

$key = $r['channelid'];

$data[$key] = $r;

}

$CACHE['channel'] = $data; //存到缓存数组

$data = array();

$r = $db->get_one("SELECT setting FROM ".TABLE_MODULE." WHERE module='phpcms'"); $CACHE['phpcms'] = unserialize($r['setting']);

//查询 phpcms这个模块的设置信息,大家可以看下数据库这个表内容。setting 字段里面的信息是经过serialize 函数窜行化的。

//所以取出的内容要unserialize 反窜行.我是挺喜欢使用serialize 函数的。他可以实现把一个数组存到数据库或把一个对象存到数据库。或是拿来GET传递都行。

//太强了。大家可以试用下。可能你项目某个地方需要用到哦。

$fields = array();

$result = $db->query("SELECT * FROM ".TABLE_FIELD." ORDER BY fieldid"); //下栽模块的信息,请自己看下这个表的数据就明白

while($r = $db->fetch_array($result))

{

$tablename = $r['tablename'];

$fields[$tablename] .= ','.$r['name'];

}

$CACHE['field'] = $fields;

cache_write('common.php', $CACHE); //开始把$CACHE 数组写到 common.php 这个文本缓存里。大家可以自己去打开这个文件看下内容。一切了然

return $CACHE;

}

function cache_update($action='')//更新文本缓存。最好在后台操作使用。因为PHP的文件flock 文件锁在某些平台使用不是很好。会出现多用户同写一个文件从而破坏缓存文件

{

global $db;

$data=array();

switch($action)

{

case 'keylink';

$query=$db->query("SELECT linktext,linkurl FROM ".TABLE_KEYLINK." where passed=1");

while($r=$db->fetch_array($query)){

$data[]=$r;

}

break;

case 'reword';

$query = $db->query("SELECT word,replacement FROM ".TABLE_REWORD." where passed=1");

while($r = $db->fetch_array($query))

{

$data[]=$r;

}

break;

default:

$actions = array('keylink','reword');

array_map('cache_update', $actions);

return TRUE;

}

cache_write('cache_'.$action.'.php', $data);

return $data;

}

function cache_table()

{

global $db,$CONFIG;

$query = $db->query("SHOW TABLES FROM `".$CONFIG['dbname']."`");

/**

显示数据库里面的所有表名

*/

while($r = $db->fetch_row($query))

{

$table = $r[0];

if(preg_match("/^".$CONFIG['tablepre']."/i", $table)) //寻找表前缀等

于 $CONFIG['tablepre'] (在config.inc.php里设置) @@表前缀还有这个作用嘿嘿{

$tablename = str_replace($CONFIG['tablepre'], 'table_', $table);

$data[$tablename] = $table; // $data['table_xx'] = xx; 形式只能意会下了

}

}

$db->free_result($query); //$db->free_result() 这个类方法其实是掉用了函数:

mysql_free_result() 函数主要是为了清除数据库大的查询而占用的内存。还是有必要的哦

if(!is_dir(PHPCMS_CACHEDIR)) // 常量 PHPCMS_CACHEDIR 在 common.inc.php 里面定义的。大家不记得了去看看吧。是存放phpcms 缓存目录的路径,这里意思是:如果缓存目录不存在

{

dir_create(PHPCMS_CACHEDIR); //如果缓存目录不存在那么就创建

dir_create($CONFIG['templatescachedir']); //创建编译后的PHP模板目录,有关phpcms模板引擎编写。在下一章合适就开讲

/**

dir_create() 函数为创建目录函数。PHPCMS自己封装的,刚看了下。phpcms 挺强。这个函数还可以通过ftp 来创建目录。这样就可以解决一些开启了安全模式下的服务器对于创建目录等出现的问题因为涉及到PHP FTP 知识。所以打算讲解到下面再说。

*/

}

cache_write('table.php', $data , 'constant'); //很多朋友说找不到phpcms 表常量在那里定义的。就是在这里。

/**

cache_write() 函数在global.func.php里面定义的。是把已经从数据库取出来的数组信息写到 PHP文本上去。@@文本缓存关键的一步废话少说上菜:

function cache_write($file, $string, $type = 'array')

{

if(is_array($string)) //检测 $string 内容是字符窜的呢还是数组的,是数组的那就继续 ..

{

$type = strtolower($type);

if($type == 'array')//然后再判断这个函数的模式标致,是否为数组模式,默认为数组模式

{

$string = "";

//这个太关键了。因为我们把数据库的信息写到文本上去的时候。是以符合PHP语法的格式写进去的。为什么呢?@@ 十分废话,因为如果不是以PHP格式写到文件里面去

那么这个PHP文件怎么能给我们include 进程序运行调用呢?呵呵。知道这一点就真的明白文本缓存的实现了。忒简单。这里使用了个小技巧:使用了 var_export() 函数

这个函数会返回一个变量的字符窜形式。这个函数太有帮助了。如果没有这个函数,我们还要自己想办法实现呢。自己写一次文本缓存就明白了。会碰到这个问题的。 '\n' 这个是

文本文件的换行。初学者别把
和 '\n' 搞混罗。一个是html 的一个是文本文件的

}

elseif($type == 'constant') //以内容形式

{

$data='';

foreach($string as $key => $value) $data .= "define('".strtoupper($key)."','".addslashe s($value)."');\n";

$string = "";

如果以内容形式的话。就不是写数组到文本里面了。而是把内容都定义成常量。

}

}

$strlen = file_put_contents(PHPCMS_CACHEDIR.$file, $string);//file_put_contents()函数是PHP5才支持的效率最好。建议使用

chmod(PHPCMS_CACHEDIR.$file, 0777); 设置目录为可读可写可执行

return $strlen; //返回写到文本的字节数

}

再说多一个读缓存文件的操作函数:上菜

function cache_read($file, $mode = 'i')

{

$cachefile = PHPCMS_CACHEDIR.$file;

if(!file_exists($cachefile)) return array();

return $mode == 'i' ? include $cachefile : file_get_contents($cachefile);

}

读缓存其实就是 include php缓存文件。讲完走人

*/

return $data;

}

/**

phpcms 的所有数据库表名都用根据数据库当前的表名来用常量来进行定义。我认为这样设计不是很好。不够灵活:比如如果我们更改数据库的一个表名的话。

那么会出现找不到表的错误信息。而且想要修复还很麻烦。就是说不能随便更改表名了。不推荐大家这样写。我们可以把表名都定义在一个PHP文件里面。这样我们以后

要改某个表名,就很方便了。

*/

function cache_module($module = '')

{

global $db;

if($module)

{

$r = $db->get_one("SELECT setting,module,name,iscopy,moduledir,moduledomain FROM ".TABLE_M ODULE." WHERE module='$module'"); //模块具体信息

if($r['setting'])

{

$setting = unserialize($r['setting']); //讲过了反窜行。因为里面信息是窜行化后再存到数据库的

}

$setting['name'] = $r['name'];

$setting['moduledir'] = $r['moduledir'];

$setting['moduledomain'] = $r['moduledomain'];

$setting['linkurl'] = '';

if($r['module'] != 'phpcms' && $r['iscopy'] == 0)

{

$setting['linkurl'] = linkurl($r['moduledomain'] ? dir_path($r['moduledomain']) : $r['mod uledir'].'/');

cache_categorys($module);

}

unset($r['moduledomain']);

cache_write($module.'_setting.php', $setting);

return $setting;

}

else

{

$query = $db->query("SELECT module FROM ".TABLE_MODULE." WHERE disabled=0 ORDER by modulei d");

while($r = $db->fetch_array($query))

{

cache_module($r['module']);

$modules[] = $r['module'];

}

return $modules;

}

}

function cache_channel($channelid=0)

{

global $db;

if($channelid)

{

$data = $db->get_one("SELECT * FROM ".TABLE_CHANNEL." WHERE channelid=$channelid");

if($data && !$data['islink'])

{

if($data['setting'])

{

$setting = unserialize($data['setting']);

unset($data['setting']);

$data = is_array($setting) ? array_merge($data, $setting) : $data;

}

$data['linkurl'] = linkurl($data['linkurl']);

cache_write('channel_'.$channelid.'.php', $data);

cache_categorys($channelid);

}

}

else

{

$query = $db->query("SELECT channelid FROM ".TABLE_CHANNEL." WHERE islink=0 AND disabled=0 ORDER by channelid");

while($r = $db->fetch_array($query))

{

cache_channel($r['channelid']);

$channelids[] = $r['channelid'];

}

return $channelids;

}

}

function cache_categorys($keyid)

{

global $db,$PHPCMS,$CHANNEL;

$urlpre = '';

if(is_numeric($keyid))

{

$keyid = intval($keyid);

$module = $CHANNEL[$keyid]['module'];

$sql = " channelid=$keyid ";

}

else

{

$sql = " module='$keyid' ";

}

$catids = $data = array();

$query = $db->query("SELECT module,channelid,catid,catname,style,introduce,catpic,islink ,catdir,linkurl,parentid,arrparentid,parentdir,child,arrchildid,items,itemordertype,itemtarg et,ismenu,islist,ishtml,htmldir,prefix,urlruleid,item_prefix,item_html_urlruleid,item_php_ur lruleid FROM ".TABLE_CATEGORY." WHERE $sql ORDER by listorder,catid");

while($r = $db->fetch_array($query))

{

$r['linkurl'] = str_replace($PHPCMS['index'].'.'.$PHPCMS['fileext'], '', $r['linkurl']);

$r['linkurl'] = $urlpre ? preg_replace("|^".$urlpre."|", '', $r['linkurl']) : linkurl($ r['linkurl']);

$catid = $r['catid'];

$data[$catid] = $r;

$catids[] = $catid;

}

if($data) cache_write('categorys_'.$keyid.'.php', $data); //写缓存罗。

相关推荐
相关主题
热门推荐