喜悦国际村 
» 游客:  注册 | 登录 | 搜索 | 统计 | 喜悦证交所 | 帮助

RSS 订阅当前论坛  

【村长请吃饭啊】 ---北京诚聘--- 【你还在犹豫吗?】

上一主题 下一主题
 21  1/3  1  2  3  > 
     
标题: [原创] 浅谈PHP生成静态页的两种方法  
 
芽雨
高级会员
Rank: 4
老老会员


UID 27830
精华 0
积分 811
帖子 915
金钱 811 喜悦币
威望 0
人脉 0
阅读权限 50
注册 2004-4-15
来自 永州-->太原-->北京
状态 离线
浅谈PHP生成静态页的两种方法

本文首发http://www.yayu.org/look.php?id=72,有点不符合参赛的规矩

但没办法啊,谁让村路被堵了那?!不能怪偶啊,再说上面的站是偶的个人网站......


最近作的一个项目中用到了两种用PHP生成静态页面的方法,回想起当初自己还不知道如何生成静态页面的迷惘,以及看不懂高手写的文章的痛苦,觉得自己有必要站出来为还不知道如何生成静态页的phper写一个通俗点文章,以帮助他们尽快掌握这个好东西。

在我之前所见的文章中要不是用代码堆砌空间就是用高手与高手交流用的语言让新人望而生却。因此本文尽量把整体思路说得详尽点。

两种方法简单说明如下:
1. 使用文件函数得到静态页面的模板字符串,然后用str_replace函数将需要替换的东西替换了再写入到新的文件中。
2. 利用PHP的输出控制函数(Output Control)得到静态页面字符串,再写入到新的文件中。

下面开始详细的说明。

一. 利用模板生成

什么是模板?如果大家使用过Dreamwerver中的“另存为模板”就应该知道模板是用来统一风格的东西。它只让你修改页面的某一部分,当然这“某一部分”是由你来确定的。本文在这说的模板也就是这个意思。(此外,PHP模板技术还包括phplib、smarty等等,这不是本文所说内容了)

把模板的概念结合本文再说得具体一点就是:美工先做好一个页面,然后我们把这个页面当作模板(要注意的是这个模板就没必要使用<!-- TemplateBeginEditable name="EditRegion3" -->EditRegion3<!-- TemplateEndEditable -->这样的代码了,这种代码是Dreamwerver为了方便自己设计而弄的标识),把这个模板中我们需要改变的地方用一个与HTML可以区分的字符代替,如“{title}”、“[title]”。在生成静态页面的时候只需要把数据和这些字符串替换即可。这就是模板的含义了。

下面来说一下具体的实现思路:做一个模板――在模板里面把需要改变的地方用特殊的字符代替――将模板中的内容取出来存放到一个字符串中(这个字符串的内容就是HTML代码和上面所说的特殊字符了)――使用函数将这个字符串里面的特殊字符用我们需要在页面上显示的内容替换――把替换后的字符串写到一个新的.htm页面里面――成功了!

功能的实现离不开PHP函数的帮忙。知道整体思路后最重要的就是去手册里面找相关的函数了。

首先,我们要把模板里面的HTML代码取出来放到一个变量中去,这个变量的值就是包含HTML的字符串了。我们可以使用string fread ( int handle, int length )函数来实现,仔细一看里面的参数“handle”是一个文件指针,这意味着我们得先把模板文件打开(PHP这一点相当麻烦,难道它就不能弄得一步到位吗!!!)。好,我们继续找能把文件打开的函数:resource fopen ( string filename, string mode [, bool use_include_path [, resource zcontext]] ),在这里我们只要传入前两个参数就可以了,第一个参数就是文件名字了,记得路径不要弄错;第二个参数建议使用“rb”,“r”代表只读方式打开,并将文件指针指向文件头,“b” 是指强制使用二进制模式,手册中建议:为移植性考虑,强烈建议在用 fopen() 打开文件时总是使用 'b' 标记。
在这一步我们的代码可以这样写:

<?php
$filemodel
="template/it.php";                 #模板地址
$file=fopen($filemodel,"rb");                 #打开模板,得到文件指针
$temp=fread($file,filesize($filemodel));         #得到模板文件html代码
?>
提醒一下:如果你只是想将一个文件的内容读入到一个字符串中,用 file_get_contents(),它的性能比fread()的代码好得多(这是手册上的原话,不过这个函数是在PHP5中支持的)。

第二步,使用str_replace()函数将得到的文件字符替换相关内容,替换的方法就是把从数据库中取出的内容或通过表单的得到的数据把模板中的特殊字符替换了。这一步很简单,也许刚开始想不明白,但是一看代码就一目了然了:

<?php
$temp
=str_replace("[title]",$title,$temp);
?>
上面的“"[title]"”就是模板文件中的特殊字符(是[title],不是”[title]”),“$title”就是我们想在页面上显示的内容,“$temp”就是模板文件html代码了。

如果还需要替换,则继续使用str_replace()函数就可以了,如:

<?php
$temp
=str_replace("[postTime]",$postTime,$temp);
$temp=str_replace("[content]",$content,$temp);
?>
第三步,也就是第一步的反操作了:要把之前处理过的模板字符串写入另一个文件中去,而这个文件就是我们最终可以对外显示的页面。现在重复类似第一步的二部曲:打开文件,写入文件:

<?php
fwrite
(fopen("$filename","wb"),$temp); #$filename是静态页面的文件名
?>
fwrite的作用就是把字符串的内容写入文件中去了。

同样,也可以使用file_put_contents函数写文件,但记得是在PHP5中。

这样,我们就可以用模板生成静态页面了。

二. 利用输出控制函数(Output Control)生成静态页面

这个与用模板生成的相比相对高级一点,但一旦明白了它的实现思路,却是简单无比,所谓会者不难,难者不会大概就是这么一回事吧。

这种方法比模板生成的方法应用面更大。使用模板生成方法一般用于发表或修改文章时使用,这样的话数据库可以直接从表单得到,就无须通过数据库了。当如果需要从数据库取出数据,并且替换的东西比较多,更或者你需要的页面并不仅仅是通过简单的替换就能得到的,比如说站点的首页。这时,就有必要考虑使用输出控制函数了。

输出控制函数的作用是设置缓冲区,在缓冲区里面输出的内容可以被获得。获得输出内容整个过程只需要使用三个函数便可以了:ob_start()、ob_get_contents()、ob_end_clean()

方法思路如下:设置缓冲区起点(或设置输出内容的起点)――释放内容――取得内容――清空缓冲区――把取得的内容写如文件。

相关函数说明如下:
1、ob_start :打开输出缓冲区   
函数格式:void ob_start(void)   
说明:当缓冲区激活时,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区。  
为了输出缓冲区的内容,可以使用ob_end_flush()或flush()输出缓冲区的内容。   
2 、ob_get_contents :返回内部缓冲区的内容。   
使用方法:string ob_get_contents(void)   
说明:这个函数会返回当前缓冲区中的内容,如果输出缓冲区没有激活,则返回 FALSE 。  
3、ob_end_clean:删除内部缓冲区的内容,并且关闭内部缓冲区   
使用方法:void ob_end_clean(void)   
说明:这个函数不会输出内部缓冲区的内容而是把它删除!

精彩开始了,看看我们是如何利用输出缓冲生成静态页面的:

我们用函数来实现吧!

<?php
#write by yayu
function createStaticPage($sourcePage,$objectPage)#来源文件,目标文件
{
#得到两个参数,一个是来源文件地址,一个是需要生成的静态页面地址
 
global $db;  #数据库连接用的,在$sourcePage中需要用到

 
ob_start(); #打开缓冲区,相当于做了一个用来存放东西的箱子
 
 
include $sourcePage;  #在缓冲区中释放页面,从这个代码中应该可以明白一点:那就是$sourcePage页面单独查看的时候,它是可以显示的!这是关键之所在,如果后面不加ob_end_clean()函数,那在执行程序的时候你看见$sourcePage页面的内容。

 
$cons=ob_get_contents();  #得到缓冲区中的内容,这里的内容就是HTML代码!这相当于把箱子里面的东西转给了一个人!
 
 
ob_end_clean();  #清除缓冲区的内容,把箱子里面的东西转给他人后,打扫卫生,不打扫卫生的后果是让他人可以看见箱子的东西,也即可以看见$sourcePage页面的内容
 
 
$fp=fopen($objectPage,"wb") or die("静态生成时打开文件".$objectPage."时出错");
 
 
fwrite($fp,$cons);  #把HTML代码写入静态文件中!
 
 
fclose($fp);
 
 return 
true;
}
?>
总结:
1. 两种方法都有把内容写入你要生成的静态页面中的一步。
2. 当可以使用第一种方法时就使用第一种方法,因为第二种方法要通过数据库调内容并显示(也可以说是隐藏了显示的内容,但事实上$sourcePage里的程序是执行的)的过程。
3. 具体情况其他分析,在使用模板生成时由于可能直接使用表单提交的内容,所以需要过滤之类的检查。
2006-12-29 06:39 PM#1
查看资料  访问主页  Blog  发短消息  QQ  顶部
 
uuq
高级会员
Rank: 4
中级会员


UID 28149
精华 1
积分 821
帖子 859
金钱 811 喜悦币
威望 10
人脉 0
阅读权限 50
注册 2004-4-27
来自 广州
状态 离线
[推荐阅读] 如何实现面板的伸缩?????
差不多,如果用模板的话跟后面那种差不多
2006-12-29 08:25 PM#2
查看资料  发短消息  顶部
 
qh663
版主
Rank: 7Rank: 7Rank: 7
中级会员


UID 30020
精华 0
积分 546
帖子 580
金钱 546 喜悦币
威望 0
人脉 0
阅读权限 100
注册 2004-7-13
来自 河源
状态 离线
[推荐阅读] 高手进入
生成静态页文件基本上都差不多,主要是看怎么与动态很好地结合起来。



五百多篇PHP学习资料
喜悦村BLOG
php团队接兼职项目QQ:80031807
PHP群:768844
2006-12-30 02:00 PM#3
查看资料  访问主页  Blog  发短消息  QQ  顶部
 
sanders_yao
版主
Rank: 7Rank: 7Rank: 7
or2 =333


UID 30286
精华 0
积分 2487
帖子 4632
金钱 2484 喜悦币
威望 0
人脉 3
阅读权限 100
注册 2004-7-23
来自 北京 菜户营
状态 离线
[推荐阅读] 这个 读网页的类怎么用????????????


QUOTE:
原帖由 qh663 于 2006-12-30 02:00 PM 发表
生成静态页文件基本上都差不多,主要是看怎么与动态很好地结合起来。
我用动态的缓存 三个函数实现最简单的缓存更能
function getQueryCache($key){
        $cacFile = "cache/" . $key . ".php";
        if(file_exists($cacFile)){
                @include($cacFile);
                return $cacValue;
        }
        return false;
}
function setQueryCache($key, & $result){
        $cacFile = "cache/" . $key . ".php";
        $fp = fopen($cacFile, "w");
        if(false != $fp){
                fwrite($fp, "<?php\n\$cacValue = " . var_export($result, true) . "\n?>");
                fclose($fp);
                return true;
        }
        return false;
}
function refreshCache(){
        $cacDir        = "cache";
        $now        = time();
        $refreshStatus = false;
        @include($cacDir . "/cfg.php");
        if(isset($cacheConfig)){
                foreach($cacheConfig as $i => $cache){
                        if(($cache["rtime"] + $cache["ttl"]) < $now){
                                unlink($cacDir . "/" . $cache["file"] . ".php");
                                $cacheConfig[$i]["rtime"] = $now;
                                $refreshStatus = true;
                        }
                }
                if($refreshStatus){
                        if($fp = fopen($cacDir . "/cfg.php", "w")){
                                fwrite($fp, "<?php\n\$cacheConfig = " . var_export($cacheConfig, true) . "\n?>");
                                fclose($fp);
                        }
                }
        }
}
2006-12-30 02:45 PM#4
查看资料  Blog  发短消息  顶部
 
millken
高级会员
Rank: 4



UID 73040
精华 0
积分 692
帖子 422
金钱 692 喜悦币
威望 0
人脉 0
阅读权限 50
注册 2006-5-9
来自 REFERER
状态 离线
[推荐阅读] 村子发地震?
我的也和这差不多,实现了数据库缓存。具体应用在www.tvbar.net(正在测试)。

以前直接调用mysql查询首页载入约需1.8s,用了cache后,载入只需0.8s。而两天才查询数据库一次。




硬盘挂了,东东丢了.
2006-12-30 06:09 PM#5
查看资料  访问主页  Blog  发短消息  顶部
 
dvaknheo
乞丐




UID 84538
精华 0
积分 -104
帖子 18
金钱 -104 喜悦币
威望 0
人脉 0
阅读权限 1
注册 2006-12-10
状态 离线
[推荐阅读] 关于数据库 连表 和 IN 的效率问题
想过一种思路:
index.htm:

<html>
<title>hello</title>
<body>
<img src='staticlib.php?source=index.htm' />
</body>
</html>
index.back.php

<?php $title='hello' ?>
<html>
<title><?php echo $title?></title>
<body>
<img src='static.php?source=index.htm' />
</body>
</html>
staticlib.php
根据设置与 参数 ,判断是否要由  index.back.php  重新生成 index.htm 最简单的,用 fopen 就可以了
2006-12-30 10:45 PM#6
查看资料  发短消息  顶部
 
芽雨
高级会员
Rank: 4
老老会员


UID 27830
精华 0
积分 811
帖子 915
金钱 811 喜悦币
威望 0
人脉 0
阅读权限 50
注册 2004-4-15
来自 永州-->太原-->北京
状态 离线
[推荐阅读] 今天看php类介绍时一个问题想不明白,请高手指点
<img src='static.php?source=index.htm' />

????

<img />还能这么用?
2006-12-30 11:17 PM#7
查看资料  访问主页  Blog  发短消息  QQ  顶部
 
nany
论坛元老
Rank: 8Rank: 8
乞丐上路


UID 20308
精华 0
积分 7460
帖子 1402
金钱 7460 喜悦币
威望 0
人脉 0
阅读权限 90
注册 2003-5-31
来自 北京
状态 离线
[推荐阅读] 这个函数可以将excel读取的字符转换,但无法正常转换数字,需要怎么处理?
个人觉得还是缓存的静态页面好一些



*****足球之夜*****
http://club.cn.yahoo.com/fifa
2007-1-4 05:21 PM#8
查看资料  访问主页  Blog  发短消息  顶部
 
sanshi0815 (sanshi0815)
高级会员
Rank: 4
中级会员



UID 63534
精华 1
积分 533
帖子 669
金钱 523 喜悦币
威望 10
人脉 0
阅读权限 50
注册 2005-3-18
状态 离线
[推荐阅读] 截图
关于首页,我主张使用,块静态文件,也就是说动态的首页,只是通过php加载一些,生成好的静态文件,这个应用一般是用在首页更新频繁的时候,如果不频繁,做静态首页还是比较实惠的
2007-1-4 05:28 PM#9
查看资料  Blog  发短消息  QQ  顶部
 
奶瓶 (NP博士)
版主
Rank: 7Rank: 7Rank: 7
老仙


UID 52707
精华 4
积分 5282
帖子 5760
金钱 5232 喜悦币
威望 50
人脉 0
阅读权限 100
注册 2004-11-22
来自 北大中文系
状态 离线
[推荐阅读] 一切都是为钱......无良的商人
变态的方法:在Apache上截获所有输出,把输出流重定向到文件,呵呵~~




图片包子,注册送100包子!
2007-1-4 10:52 PM#10
查看资料  访问主页  Blog  发短消息  QQ  ICQ 状态  Yahoo!  顶部
 21  1/3  1  2  3  > 
     


  可打印版本 | 推荐给朋友 | 订阅主题 | 收藏主题 | 开通个人空间  


 


Powered by Discuz! 6.1.0  © 2001-2010 Comsenz Inc.
Processed in 0.032559 second(s), 6 queries

(冀ICP备05009913号) 管理员:sadly 邮箱/MSN: sadly@phpx.com QQ:824008(长隐) 清除 Cookies - - Archiver - WAP