php 生成静态页面
在喜悦国际村看到的一篇讨论贴还可以
静态页面的生成一般有这么几个思路了。。
1。程序编写过程中。不使用直接输出的语句。而时将所有的输出连接至输出字符串,输出完成后。再直接将输出字符串内容写入文件
2。编写中按照正常的方式编写。通过ob函数组捕获输出。然后将输出写入文件
3。使用模板类时,用get/fetch一类的方法获取输出。并写入文件。
具体实现上又有这两种方法
1。管理后台添加记录时,直接生成目标html页面,并且前台调用连接直接指向生成的html页面。这种方法程优点是程序效率最高。服务器负荷轻,不过由于生成的是纯静态页面,一旦页面样式上有所改动就必须重新生成所有的内容页。所以实际使用中应用一般不是太多。更多的是使用js,ssi,xml/xsl等客户端手段,生成的静态文件中仅保存数据,不涉及样式,这样能达到速度和维护性的平衡,不过相对前后台程序要复杂些(应用这种方法时,由于内容为纯静态,可以搭配单独编译的纯静态的apache使用。。效率和资源占用上比包含动态内容支持的要更佳)
2。前台访问链接指向php程序,php程序首先检查是否存在相应的静态文件。如果静态文 件不存在。则生成并重定向至此文件,否则直接重定向。这种方法实际使用中一般和apache的url_rewrite功能一起使用。将php的文件地址重 为html的形式,有利于搜索引擎的检索。这种方法在效率上略有损失,不过程序结构简单,便于调整,在访问量不是很大时使用很合适。。
下面是此村村长说的,讲得很好
生成静态页的主要目的是什么? 提高效率.
在这里我以村子为例来说明我的构架, 请注意, 这个构架没有完全在村子使用.
———————–用户读帖子,存在静态页————–A————–
用户 :访问 http://www.phpx.com/happy/static/top92092.html
apache: 文件存在. 输出文件
用户 :得到页面
———————–用户读帖子,静态页未生成或已删除—-B————–
用户 : 访问 http://www.phpx.com/happy/static/top92092.html
apache: 文件不存在. 重定向到404处理程序 (httpd.conf加 ErrorDocument 404 /errprocess.php 指令)
errprocess.php: 得到用户请求的页面及各种变量. 是否需要进行生成静态的页面?
首字母为: top ,是需要生成的页面,调用showthread.php (需改进结构将页面输出到变量$pagecontent)
得到页面的内容$pagecontent, 将$pagecontent存成静态文件 top92092.html,
最后可以:
a) header(”location:http://www.phpx.com/happy/static/top92092.html“)
b) header(”HTTP/1.1 200 OK”); 以后 直接输出$pagecontent, 要注意img src等相对链接的位置了!!!
用户 : 得到页面 或者重定向到 A 操作.
———————–用户回帖子————————–C————-
用户 : 回复帖子 top92092.html
newreply.php: 删除静态文件 top92092.html (如果用户信息也是生成静态js, 还要同时删除 用户id.js )
数据入库等常规操作.
最后可以:
a) header(”location:http://www.phpx.com/happy/static/top92092id.html“)
b) 或者改进 newreply.php 在入库后, 调用 showthread.php 得到页面的内容$pagecontent,
将$pagecontent存成静态文件 top92092.html, 输出$pagecontent;不过为了方法统一,
建议使用b)重定向只使用一个静态生成点.
用户 :用户得到页面 或 到B操作
———————–用户发表新帖————————D————
用户 : 发表新帖子
newthread.php: (如果用户信息也是生成静态js, 还要同时删除 用户id.js ) 数据入库等常规操作.
最后可以:
a) header(”location:http://www.phpx.com/happy/static/top新帖id.html“)
b) 或者改进 newthread.php 在入库后, 调用 showthread.php 得到页面的内容$pagecontent,
将$pagecontent存成静态文件 top92092.html, 输出$pagecontent;不过为了方法统一,
建议使用b)重定向只使用一个静态生成点.
用户 :用户得到页面 或 到B操作
———————–村子更换html风格———————E———
管理员: 删除 static 目录下的全部文件
用户访问页面, 页面不存在, 执行 B 操作
(
关键点:
1 不可以直接http://www.phpx.com/happy/top92092.html 这样其他设计的时候有问题
2 要注意文件位置, 比如 happy/images/a.gif 用户访问 happy/showthread.php时
代码写成 <img src=images/a.gif> 看到是对的. 而生成静态页后. 页面位置变成了
happy/static/top92092.html 这时图片的位置就不对了. 变成了 ../images/a.gif
所以showthread.php 写成 <image=”/happy/images/a.gif”> 就不会有错了.
这当然会带来一些问题比如以后访问位置改成 www.phpx.com/bbs/ 那showthread.php代码
就需要修改了. 类似的还有很多, 比如javascript一类的.
3 帖子需要统计点击率, 怎么实现? 在生成文件时加代码 <img src=/happy/clicked.php?id=92092 width=1 height=1> ,由clicked.php 去更新点击数
4 用户信息, 如用户发贴数怎样保持最新? 用javascript
a) 将用户信息部分改成 <script src=/happy/uinfo.php?uid=用户的id></script> 这样无论用户发贴数变化或者更新头像都是没有问题的
b)用户信息也用其类似办法生成静态 <script src=/happy/static/用户的id.js></script>
5)一个目录下的文件过多就会有问题了.如果帖子量很大 ,全部指向 /happy/static/top帖子id.html
不再是一个好的设计. 可以做变通处理 比如 /happy/static/版面id/top帖子id.html 将每个版面的
帖子放置一个目录等. 类似的算法还很多.
6) 这种设计会提高效率么?
我们来算算就知道了
不采用以上结构. 一个帖子帖子有10个回复 和 100次浏览(简单计算, 不考虑帖子锁定, 用户权限等等)
每次浏览 需选出帖子内容,选出每个帖子的用户信息(使用join操作) 更新点击数. 100*3 =300次 数据库查询
每次回复 帖子入库 更新原帖回复数, 更新用户发贴数. 10*2 =20次 数据库查询
也就是这个例子需要做 320次数据库查询. 而且其中在浏览时要将用户表 和 帖子表做join
这两个表通常会比较大.(如果不做join, 至少每次浏览加一次数据库查询. 因为帖子已经选出, 可以遍历获得全部发贴
人的id, 再select ** where uid in (全部发帖人id) 获得这些人的信息 )
采用静态结构的情况:
a) 用户信息动态
浏览: 有10个回复, 则被删除十次.
生成10次静态文件, 需做需选出帖子内容,选出每个帖子的用户信息(使用join操作)操作: 10*2=20次
100次浏览: clicked.php更新帖子点击数 100*1 =100 次 uinfo.php 获得信息 100*1 =100 次
每次回复 帖子入库 更新原帖回复数, 更新用户发贴数. 10*2 =20次 数据库查询
总共需要240次数据库查询
b) 用户信息也静态
浏览: 有10个回复, 则被删除十次.
生成10次静态文件, 需做需选出帖子内容,选出每个帖子的用户信息(使用join操作)操作: 10*2=20次
100次浏览: clicked.php更新帖子点击数 100*1 =100 次
每次回复 帖子入库 更新原帖回复数, 更新用户发贴数. 10*2 =20次 数据库查询
生成新的userid.js 10*1 =10次 数据库查询
总共需要150次数据库查询
对比, 前者需要320次查询, 其中100次为两个大表join .
a) 需要240次数据库查询,10次大表join
b) 需要150次数据库查询,10次大表join
这里面还没有考虑调用 静态页 和 调用php的内存及cpu开销. 仅数据库一项差距就比较大了.
404 主要还是为了最大限度的提升性能.
下面再就 404方式和php cache 做一个比较.
(这里假设showart.php 为php cache的运行程序)
文件存在时:
php cache方式 ( showart.php ? id=1234)
apache IO判断 showart.php 是否存在 , 装入showart.php
showart.php IO判断是否存在 static/1234.html . 文件存在, 输出
两次IO. 其中一次为apache ,一次为 showart.php
404 方式 ( static/1234.html)
apache IO判断 static/1234.html 是否存在,文件存在, 输出
Apache有一次IO
文件不存在时:
php cache方式 ( showart.php ? id=1234)
apache IO判断 showart.php 是否存在 , 装入showart.php
showart.php IO判断是否存在 static/1234.html . 文件不存在,
showart.php 调用 showthread.php 取得页面内容,
生成static/1234.html . 输出
四次IO , apache 一次, showart.php 三次
404 方式 ( static/1234.html)
apache IO判断 static/1234.html 是否存在,文件不存在,
apache IO判断 errprocess.php 是否存在 , 装入errprocess.php
errprocess.php 调用 showthread.php 取得页面内容,
生成static/1234.html . 输出
四次IO , apache 两次, showart.php 两次
以上的计算是近似计算不是实际情况. 但是数量基本是正确的.
而一个页面, 大部分时间是存在访问, 少量时间是不存在访问.
比如BBS帖子, 看帖和发贴的比率至少有5:1 吧.
如果是新闻类的内容. 估计就更大, 可能达到 数百, 数千比一
尽管每一次访问减少是一次IO. 但是访问量增大的时候, 效果就非常明显.
这里还没有考虑存在访问时的内存效率
另外 apache io 的效率要高于php io
1。对于同一目录下文件过多引起性能问题的解决方法
a.对帖子id根据数据库中字段长度做str_pad:比方说id为123456,数据库中为int(11),则id处理为00000123456,
b.考虑到lux下一般同一下文件到达四位数会有性能影响,对其做切割,最后路径为static/00/000/123/456.html
c.然后以此为路径储存生成的文件(注意要兴建逐层的路径,分割没必要太细,否则会大大增加磁盘空间占用,降低系统性能)
2。每次回复帖子都要删除文件。并重新读取数据库,重新生成整个帖子文件这块似乎有些繁琐。这块的操作也是很多的。
我的方法是帖子数据用js来储存数据,这样回复帖子/编辑帖子时候只要根据表单数据对js文本进行累加就行了。。避免了频繁的删除,兴建文件和读取数据库带来的性能影响,不过对js处理时候要注意文件的锁定。
3。对于用户信息。头像等动态内容的处理
由于同一个帖子页面中往往有数十个用户信息需要获取。如果直接用<script>的方法读取那么就需要打开数十个http连接。无论从client和server短都是个不小的负担。也减慢了整体速度。
这里可以吧所有的用户id连接起来。通过一个<script>标签一次性取出,并存入数组。调用的时候通过js函数来显示。这样效率会更高。而且服务器压力更小
原地址:http://www.phpx.com/happy/viewthread.php?tid=92092&extra=&highlight=%BE%B2%CC%AC&page=4