Chinaunix首页 | 论坛 | 博客
  • 博客访问: 198645
  • 博文数量: 264
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 2740
  • 用 户 组: 普通用户
  • 注册时间: 2009-06-03 13:25
文章分类

全部博文(264)

文章存档

2011年(1)

2009年(263)

我的朋友

分类:

2009-06-03 15:22:36

现在开始讲  index.php 首页文件. 基本来说PHPCMS的加载到显示操作的整个流程都分析完了.大家看一遍后.还要整体的来看来分析.慢慢体会.把些好的思想和思路实现到自己以后的项目 里.我相信大家都会变得很强的. 记得: 程序是死的,人是活的.有实现思路一切都好办了.php 

/**

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

*/

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

/**

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

*/

if($PHPCMS['ishtml'] == && 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'] == && $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协议,会有详细的参数说明 。其主要目的是:强制用户每次访问这个页面时获取最新资料,而不是使用存在客户端的缓存。

*/

?>


/**

函数 template函数是在global.func.php 里面定义的。 在前面的phpcms 的首页 index.php 里就见到 了。  用法: include template()    用法很熟, 呵呵其实和 dz 的模板引擎一样的用法。 但DZ的模板引擎 比 PHPCMS 的简单很多,因为没有用到模板的标签技术。 大家有空可以研究下DZ的模板引擎。这里不说。  好分析下上面这个 模板的主要函数 吧。  他的作用是返回编译好的模板文件路径。也就是把模板 X.html(模板文件) 用正则替换成 x.php(编译后的PHP文件).然后使 用 include  函数。懂了吧! php的模板引擎都一个鸟样。 然后剩下的就是正则的东西了。等下再说。 

*/

function template($module 'phpcms'$template 'index')

{

 global 
$CONFIG;

 
$compiledtplfile $CONFIG['templatescachedir'].$module.'_'.$template.'.tpl.php';

 
/**

 因为phpcms是分模块来存放模板文件。所以 template 函数有两个参数: 第一个就是模块目录名,第二个就是此模块里面的模板文件名.

 $CONFIG['templatescachedir']  这个是放编译后php文件存放的目录。在config.inc.php 站点配置文件里面定义的自己去看。 这样就取得了模板编译后的php文件路径。

 */

 
if($CONFIG['templaterefresh']) //$CONFIG['templaterefresh']  在 config.inc.php里面配置了。默认是1  。是更新模板开关。如果你设置为0 那么模板更新了。程序也不会更新。

 
{

        
$tplfile PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/'.$template.'.html';

  
/**

  和上面那句意思差不多。$CONFIG['defaulttemplate'] 是默认模板目录  。这句是获取你要的那个模块和里面的那个模板文件的路径(@@获取没编译前的模板文件)

  */

        
if(!file_exists($compiledtplfile) || @filemtime($tplfile) > @filemtime($compiledtplfile))

  {

   
/**

   我把文件编译成了php文件。那么模板改变了。 php文件总得也改变吧。要不你修改了模板后。站还是以前那个样子没变那有什么意思呢。

   首先判断模板编译文件是否存在。如果不存在那么后边那个条件不用判断了。 因为编译文件都不存在。程序肯定运行不了拉。(因为其实我们主要是运行编译后的那个php文件,模板文件是html的运行个P呀)

   或  后边那个 @filemtime($tplfile) > @filemtime($compiledtplfile)  很 容易就明白:  函数 filetime() 判断文件最近修改的时间,返回Unix 时间戳。 如果模板文件的修改时间 大于 编译文件。 那么证 明 模板文件  在 编译文件生成后 还进行了修改。那么我们是不是还要在更新次编译文件呀 ,那是肯定的拉。 所以继续执行下去。

   */

   
require_once PHPCMS_ROOT.'/include/template.func.php';   // 加载编译函数

   
template_refresh($tplfile$compiledtplfile);// 这个就是模板的 编译启动函数 ,带动一系列的模板编译函数来最终生成模板编译文件。

  
}

 }

 return 
$compiledtplfile// 返回 模板编译后的PHP文件路径。

}



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

function 
template_compile($module,$template//和下面那个一样是编译模板启动函数。不过两函数的参数不一样,按照上下文意思。这个函数是为了配合批量编译模板而写的。第一个是模块目录名,第二是模板文件名,解释同下。请看下面那个

{

 global 
$CONFIG;

 
$content file_get_contents(PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/'.$template.'.html');

 
$content template_parse($content);

 
$compiledtplfile $CONFIG['templatescachedir'].$module.'_'.$template.'.tpl.php';

 
$strlen file_put_contents($compiledtplfile$content);

 @
chmod($compiledtplfile0777);

 return 
$strlen;

}

function 
template_refresh($tplfile,$compiledtplfile//模板编译启动函数。 参数 第一个是 模板文件名  第二个是 编译后的php文件名

{

 
$str file_get_contents($tplfile); //使用了php5 的最爽函数:file_get_contents() 获取文件的内容 。

 
$str template_parse($str); /*然后 使用 template_parse() 函数来对文件内容进行替换。比如把一些我们自己定义的语句:{if xx > xx}  正则替换成  xx){?>具体看下面*/

 
$strlen file_put_contents($compiledtplfile$str);//编译完成后。把内容写到我们的 那个所谓的编译PHP文件。

 
@chmod($compiledtplfile0777);  //别忘了设置下权限。

 
return $strlen//返回 写到编译文件里的内容字大小节数,下面我们看下 template_parse() 函数

}

function 
template_module($module)//这个很有用。批量编译某模块目录下的模板文件

{

 global 
$CONFIG;

 
$files glob(PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/'.$module.'/*.html');

 
/*

 glob 函数  取得 在此路径下的所有 *.html 以html为扩展名的文件列表。 具体看手册。

 **/

 
if(is_array($files))

 {

  foreach(
$files as $tpl)

  { 
//开始批量

   
$template str_replace('.html'''basename($tpl));

   
// 获取模板文件名。以次来做编译后的PHP文件名

   
template_compile($module$template); //这个函数上面讲过了。看上面

  
}

 }

 return 
TRUE;

}

function 
template_cache() //这个是比上面那个更大批量的生成。因为 $MODULE 里面的所有模块  $MODULE 存在于缓存文件模板。前面已经说了。自己看吧

{

    global 
$MODULE;

 foreach(
$MODULE as $module=>$m)

    {

        
template_module($module);

 }

 return 
TRUE;

}

/**

哇,别给它吓到。其实都是些简单的正则。只要知道他们是干什么的就好办了。 在模板里面我们使用了些自己定义的标签呀。语句呀。这些东西不是PHP标准语法。所以根本不可能运行。

那么怎么办呢。通过正则对我们自己定义的语法 。转变成标准的PHP语法。然后写到我们的 PHP文件里。所以下面正则都是对我们自己定义的语法进行编译。

下面讲解下正则。按照本人水平解释。大概的解释了下。不过不懂正则的请自己百度学下。有不对的地方。大家可以讨论下。@@   还没懂 preg_replace() 函数的同学兄弟朋友姐妹。请自己看手册。

*/

function template_parse($str)

{

 
$str preg_replace("/([\n\r]+)\t+/s","[url=file://\\1]\\1",$str[/url]);  

 
// 用 \n\r 过滤掉 tab制表符,  [url=file://\\1]\\1[/url] 是逆向引用了第一个括号里面\n换行\r换页匹配的文本 (@@解释好要口,最好自己看下正则知识 /s为修正符。自己百度吧)

 
$str preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s""{\\1}",$str);

 
// 以 {xx} 来替换  {xx}在下面肯定还要进行第二次正则替换,要不是不能在PHP里面运行的。  .+? 和 .+ 一个是懒惰 一个是贪婪。  看名字就知道。不知道的 百度吧: 正则贪婪。

 
$str preg_replace("/\{template\s+(.+)\}/","\n\n",$str); 

 
/*把模板里面 的 {template 'xx','jj'} 编译成PHP标准写 法:   大家可能一看就明白 了: include template()  这个在那里见过。对了。这个在PHP里也可以运行的。因为 template() 函数不是定义了 吗。*/

 
$str preg_replace("/\{include\s+(.+)\}/","\n\n",$str);

 
/* 模板里面的 {include xx.php} 编译成 PHP文件里的 **/

 
$str preg_replace("/\{php\s+(.+)\}/","\n\n",$str[/url]);

 
/* 模板里面的 {php xxxx} 编 译成   大家也应该明白了。 xxxx 肯定是PHP的标准语法拉。 所以phpcms模板语 句: {php } 就是用来给你在模板里写要运行的PHP语句。在smarty 里也有这功能**/

 
$str preg_replace("/\{if\s+(.+?)\}/","",$str);

 
/* 这个就更简单了。 把模板里面的{if xxxx}  编译成   看这样一步一步的把一些自己定义的语句编译成PHP的标准语法。这个就叫模板引擎了。**/

 
$str preg_replace("/\{else\}/","",$str);

 
/* {else } 转 **/

 
$str preg_replace("/\{elseif\s+(.+?)\}/","",$str);

 
/* {elseif } 转 **/

 
$str preg_replace("/\{\/if\}/","",$str);

 
/* {/if} 转   phpcms 模板语法有: {/if}的哦。大家别忘了,要不 php肯定运行不了**/

 
$str preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/","",$str);

 
/* 下面就是循环了。模板里用{loop xx jj} 其实编译成了PHP的 foreach(xx AS jj) 这样大家都会用了吧**/

 
$str preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/","\n [url=file://\\3]\\3[/url]) { ?>",$str);

 
/* 这句和上面也差不多。不过是多了个取出数组的标名  {loop xx jj yy}  成 foreach(xx as jj=> yy)**/

 
$str preg_replace("/\{\/loop\}/","\n\n",$str);

 
/* 循环结束别忘了 {/loop}  对应PHP的 **/

 
$str preg_replace("/\{tag_([^}]+)\}/e""get_tag('\\1')"$str);

 
/* {tag_xx}  替换为 get_tag('xx')  get_tag()  函数是自己定义的函数,因为phpcms 的模板引擎应用了标签功能。这个函数就是为了调用标签的。**/

 
$str preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(([^{}]*)\))\}/","",$str[/url]);

 
/* {xxx(jj)}  这么个奇怪的东西。因为奇怪所以我找了下PHPCMS的模板文件。找了几个文件都没发现这个怪物。大家有谁找到的说下我去看下。怕是我理解错了正则。先谢了**/

 
$str preg_replace("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\(([^{}]*)\))\}/","",$str[/url]);

 
/* {$xxx(wwsd)} 专换成    当然了 xxx() 是程序中定义过的函数**/

 
$str preg_replace("/\{([url=file://\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/]\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/","",$str[/url]);

 
/* 把{$xxjj} 转成   当然了是把变量输出**/

 
$str preg_replace("/\{([url=file://\\$[a-zA-Z0-9_\[\]\]\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/es[/url]""addquote('')",$str[/url]);

 
/* 主要是把{$xxx['jj']} 转成   addquote() 函数自己定义的看下面,二次过滤。有代验证,头昏了看太久的黄色字。我昏**/

 
$str preg_replace("/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s""",$str[/url]);

 
/* {XXJJ}    XXJJ 是我们定义的常量**/

 
$str "".$str;

 
/* 最后别忘了在自己的每个编译后的文件里加上这个。以前讲过了不明白找前面例子**/

 
return $str//最后返回过滤完成的内容

}

function 
get_tag($tagname//这个函数在  上面这个编译函数里面看到了。 其实就是获取对应标签的内容,头有点昏,下节再说标签吧。

{

 global 
$tags,$html,$CONFIG;

    if(!
$tags) require PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/tags.php';

    if(!
$html) require PHPCMS_ROOT.'/templates/'.$CONFIG['defaulttemplate'].'/html.php';

 if(!isset(
$tags[$tagname])) return '{tag_'.$tagname.'}';

 
$code = isset($html[$tagname]) ? 'tag_read('.$html[$tagname].')' $tags[$tagname]; 

 return 
""

}

function 
addquote($var)



 return 
str_replace("[url=]\\\[/url]"", """preg_replace("/\[([a-zA-Z0-9_\-\.\x7f-\xff]+)\]/s""['\\1']"$var));

}

?>





阅读(197) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~