Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 15

页面静态化技术

1 页面静态化的对象:
针对的是那些修改很少,但反复查询量大的数据。

2 页面静态化的技术:
2.1 Php 自带的 ob 缓存来实现页面静态化(用于将对数据库的高访问量转变成去访问 html 静态页面,
从而实现减小数据库负担并提速,但如果更新数据后在新访问该数据时可能会产生滞后) :在
需要 echo 的内容之前开启 php 缓存,然后将缓存的内容输出存入到一个 html 文件:缺点是
(1)当更新数据后,html 不会变化,只能通过每过一段时间更新一下 html 文件,这样 html 文
件会有延时;(2)查询某个页面时,是通过 php 动态网址去访问的页面的(.php?id=…)。
2.2 真静态技术(用于将对数据库的高访问量转变成去访问 html 静态页面,从而实现减小数据库负
担并提速,且保证数据实时性,但可能会产生海量 html 文件):真静态可以解决 php 自带缓存
实现静态化中的延时问题,它的技术和 php 缓存完全不同。它在数据第一次 INSERT 到数据库时
同时创造 html 文件,当再次访问数据时,就直接访问相同 id 的 html 文件,而不再访问数据库。
所以,真静态即解决了服务器对数据库高并发访问的问题,同时也实时更新了 html 静态文件
(即解决了 php 缓存实现静态化所带来的延迟问题),它解决了访问量大或访问频繁的问题。
但如果该应用程序有海量数据(海量 id),真静态就会产生问题,因为会造成创建大量的 html
文件,就会(1)占用大量磁盘,(2)查询海量 html 文件同样有速度问题。相对好一些的做法
是,可以按照某种规则,比如将 html 文件按日期存入不同文件夹,这样也可以相对环节查询的
速度,但是磁盘占用大是无法解决的。
2.3 伪静态技术(用于优化 seo):伪静态技术只是把动态页面的动态网址(.php)改写成静态网址
的形式(.html),伪静态网址并不是让动态网页静态化,对网页访问时还是和原来一样会访问
数据库。所以,并不能解决高并发访问数据库的问题,但它适合 seo。如果只是为了 seo,就只
是用伪静态技术就可以了。如果网站要 seo,数据量(id)也非常海量,但一般只会查询少部分
的 id,比如电话费查询系统,数据库存储并可以查询用户所有月份的电话费(比如 10 年),这
样就会产生海量 id,显然用真静态不太合适,而根据实际情况,用户一般都只会查询近 3 个月
的电话费,这样实际上并不产生海量 id,所以可以使用“伪静态技术(seo 好)+php 自带 ob 缓
存(在查询时创建 html 文件)”。但是,随着时间和访问量的推移,数据会越来越庞大,最终
会趋向于海量 id,变成真静态的海量 html 文件的结果。

3 基本概念
3.1 静态页面:是不操作数据库的 html 文件。
3.2 动 态 页 面 : php 网 址 如 : http://localhost/news.php , 或 : http://localhost/news.php?
lang=cn&class=1&id=2。
3.3 伪静态:是把动态页面的动态网址改写成静态网址的形式,但文件的内容还是和原来一样会操
作数据库。如:http://localhost/news-cn-class1-id2.html。

4 为什么要进行页面静态化的三个好处:
4.1 访问速度:内存>文件>数据库。由于数据库访问速度最慢,且如果过高并发访问数据库会使数
据库崩溃,所以在有可能的情况下应尽量减少对数据库的读取,特别是哪些不太修改单会反复
去读取的数据,可以将数据存到文件中,每次去读取文件,来代替读取数据库。这就是页面静
态化技术。
4.2 访问 php 的速度比 html 慢:
4.2.1 在 apache/bin 的 ab.exe 工具,可以做压力测试,可以模拟多人并发访问某个页面。
4.2.2 测试将返回的指标:
 文件大小
 平均每秒执行的访问次数 Requests per second
 平均每次访问的响应时间 Time per request
4.2.3 测试:
1) 在 cmd 中进入到 apache/bin 下。
2) 执行语句:(ab.exe -n 执行次数 -c 并发数 访问页面地址)
说明:c 表示用户并发数,n 表示每个用户执行访问次数。
比如:ab.exe -n 10000 -c 10 http://text.php
3) 比如:
test.php
<?php
for($i=0,$i<100,$i++) {echo $i;}
?>
测试:ab.exe -n 10000 -c 10 http://text.php
test.html
01234……99
测试:ab.exe -n 10000 -c 10 http://text.html
测试结果会证明,访问 php 的速度比 html 慢。

4.3 静态化利于 seo:即 search engine optimization,搜索引擎优化。目前,最主要的两大搜索引起


就是百度 baidu 和谷歌 google(其他诸如雅虎等都是小的搜索引擎)。这些搜索引擎每过一段时
间便会在网络上去抓取各种页面,并缓存起来,即“快照”。在抓取页面时各种搜索引擎对网
址有其自己的抓取“规则”。如果 seo 不好,在该搜索引擎中,你的网页就会被往后排,自然
不利于推广。
 seo 建议:
 URL--URL 长度:百度建议 URL 的最长长度不超过 255byte。
 URL--静态页参数:在静态页面上使用动态参数,会造成 spider 多次和重复抓取。
 页面内容—Meta 信息完善程度:缺少 keywords 和 description 的 meta 标签可能会对你
网址的展现和排序产生一定影响。
 页面内容--图片 Alt 信息:加上 alt 信息后的 img 标签,可使你网页上的图片更容易被用
户检索到。
 页面内容—frame 信息:frame 标签会导致百度 spider 的抓取困难。
 对 于 动 态 网 页 , 一 般 的 做 法 就 是 使 用 动 态 网 址 , 即 比 如 : http://localhost/news.php?
lang=cn&class=1&id=2。而 seo 更倾向静态网址:
 seo 倾向于抓取 html 格式且不带有动态参数的静态页面,比如 aa.html。
 seo 不倾向于 php 格式的页面,因为如果是 php 格式,seo 会认为这是一个动态网页
(比如会和数据库发生关系),但是搜索引擎只能抓取页面,却不允许去抓取别人数
据库中的数据。
 seo 也不倾向于带有动态参数的页面,比如:news.php?lang=cn&class=1&id=2,这里带
有动态参数(cn,1,2),而这些参数可能会变化,这会造成 spider 多次和重复抓取。
 所以,对于动态网页的动态网址可以将其改成伪静态网址,则可以变为如: http://
localhost/news-cn-class1-id2.html,这样,首先先变成 seo 希望的静态网址,且网址包含
了网页的信息便于搜索引擎进行抓取,注意:网址也不能太精简,比如写成: news-
2.html,这样同样也不利于搜索引擎抓取,因为网址自身带有的信息量不够。另外,对
于 class1 还 可 以 写 的 更 好 一 点 , 比 如 如 果 1 代 表 运 动 类 , 则 可 以 改 进 成 : http://
localhost/news-cn-sport-id2.html,这样可以更好的提供信息。

4.4 静态网址或者将动态网址改写成伪静态网址可以减少 sql 注入攻击的风险: Sql 注入攻击往往更


容易从动态参数中进行注入攻击。

5 Php 自带 ob 缓存技术实现页面静态化
5.1 思路:
5.1.1 有一个 news_list.php 新闻列表中,可以点击某条新闻的详细内容连接查看详细内容<a
href="newsAcction.php?id=$id">)。当第一次点击某条新闻的详细内容时,即第一次从数据
库 SELECT 时,将需要计划 echo 到浏览器的内容进行缓存(开启缓存 ob_start();),然后
$content = ob_get_contents()来获取缓存内容,并保存到一个 html 静态文件中,文件名包含
该 数 据 的 id , 如 $html_filename="news_id".$id.".html"; file_put_contents($html_filename,
$content)。在该 newsAcction.php 脚本结束后便会自动输出新闻的详细内容。在实际代码中 ,
当希望访问某条新闻的详细内容时,先查看是否存在该条新闻的 html 文件,如果存在,直
接 echo file_get_contents($html_filename); exit(); 打印出该 html 中的内容,并退出脚本(如
果不退出,则会继续往下执行,即还是去读了数据库),如果不存在,则采用第一次访问
的方法访问数据库并创建 html 文件。
5.1.2 所以,这种方法是在第一次 SELECT 时创建 html 文件的,而不是在 INSERT 时创建 html 文件
的,这意味着不会像 INSERT 时创建 html 那样产生那么多的可能不会访问的 html 文件。但
问题是:当新闻内容被修改后,html 并不会被修改,一个解决方法是,设置一个过期时间,
比 如 30 秒 , 如 果 html 文 件 存 在 且 没 有 过 期 ( if(file_exits($html_filename) &&
filetime($html_filename)+30>time()){echo file_get_contents($html_filename); exit(); } ) , 一
旦过期,就删除该 html 文件,而当用户再次访问某条新闻时,如果文件从未被访问过(不
存在 html 文件),或者已经过期被删除(同样不存在 html 文件),就会像第一次访问某条
新闻一样,去查询数据库并创建一个 html 文件。

6 真静态技术实现页面静态化
6.1 思路:
6.1.1 对于那些不太变化,且会被很多用户读取的数据,应尽量避免反复去数据库 SELECT,且当
不会生产海量 html 文件的情况下,就可以考虑使用真静态技术实现页面静态化。其思路为
在添加 INSERT 这些数据的后可获得该条数据的 id,然后通过该 id 就同时创建对应的 html
静态文件,当下次有用户访问该数据时便可以直接 echo 出 html 文件中的内容,这些就是真
静态技术。
6.2 步骤:
6.2.1 数据列表页面 new_list.php:
 当需要读取数据时,因为在 INSERT 环节就已经创建了 html 文件,所以根据数据的 id,
直接<a href=$html_filename>到对应的$html_filename="news_id".$id.".html";的静态文
件上。
 当需要添加数据时,通过<a href="add_news.html">连接到 add_news.html 表单文件,
然后提交表单到 newsAction.php,进行数据库添加数据并创建对应 id 的 html 静态文件。
 当需要修改数据时,通过<a href="update_news.php?id=$id">连接到表单文件,并把 id
传 给 表 单 页 面 , 然 后 提 交 表 单 到 newsAction.php ( 该 $id 通 过 隐 藏 域 来 传 到
newsAction.php),进行数据库更新数据、和对应 html 静态文件的更新。
 当需要删除数据时,通过<a href="newsAction.php?id=$id">连接到 newsAction.php,进
行删除对应 id 的 html 静态文件和数据库中的数据。
6.2.2 数据处理页面 newsAction.php:
6.2.2.1 当需要添加数据到数据库时,
 执行 INSERT,存入数据库。
 INSERT 成功后会产生该条数据的 id($id=mysql_insert_id();),就可以设计 html
静态页面的文件名($html_filename="news_id".$id.".html";)。
 将会展现到浏览器的数据存入 html 文件,以便其他用户直接访问对应 id 的 html
文件。具体创建 html 文件的过程和代码见下面举例。
6.2.2.2 当需要 UPDATE 数据时,
 UPDATE 数据库中的数据。
 删除该 id 的 html 文件(unlink($html_filename);)。
 根据 INSERT 方法重新创建 html 文件。
6.2.2.3 当需要 DELETE 数据时,
 删除该 id 的 html 文件(unlink($html_filename);)。
 DELETE 数据库中的数据。

7 伪静态技术
7.1 对于诸如 http://localhost/content.php/2,111,345.html 这样的网址,会认为 content.php 是一个页
面,后面的内容(2,111,345)会被认为是带有的参数,所以还是会访问 content.php 页面。但带
有.html 这种形式的参数在 seo 中会更优于?id=value 这样形式去带参数。所以,通常我们可以把
动态网址:http://localhost/content.php?a=2&b=111&c=345,伪静态化,变为:http://localhost/
content.php/2,111,345.html。可以通过正则表达式获取参数,或也可以通过 apache 的 rewrite 机
制来获取参数。

7.2 通过正则表达式获取参数(通过$_SERVER['PATH_INFO']):
//$_SERVER 里有一个:
$para=$_SERVER['PATH_INFO'];
if(preg_match('/^\/(\d+),(\d+),(\d+)\.html/si',$para,$arr)){ //$arr[0]= /2,111,345.html; $arr[1]=2;
$arr[2]=111; $arr[3]=345.
//进一步代码
} else {
//地址有误
}

7.3 通过 apache 的 rewrite 机制来获取参数:


7.3.1 我们常规的网址是:http://localhost/news.php&id=3,我们可以将其改成稍微理想一些的网
址:http://localhost/news.php/3.html,然后通过正则表达式获取参数,但这样的网址还是
显 得 有 点 笨 重 , 比 较 理 想 的 是 可 以 写 成 : http://localhost/news-id3.html 。 而 Apache 的
rewrite 机制就可以实现将 news-id3.html 重写成 news.php&id=3。这样我们就可以将文件命
名为 news-id3.html,再让 apache 的 rewrite 机制重写成 news.php&id=3,这样,就能实现网
址静态化(html)的优化,同时实现原来 php 文件(.php?id=value)功能。
7.3.2 为了实现上面的功能,需要配置 rewite。Rewrite 是由 apache 来配置的,而不是 php 的。具
体实现的步骤如下:
7.3.2.1 基本知识点(apache/conf/httpd.conf):在 apache/conf/下打开 httpd.conf 文件,其
中<Directory></Directory>段用于对指定的目录访问权限进行配置。
 第一段<Directory></Directory>:

我们涉及到:
 (1)在首标签<Diretory>中指定一个根目录(包括该目录以及其子目录和文
件),接下来的配置针对该目录有效;
 (2)配置是否允许用户访问该根目录;
 (3)是否对该根目录下的内容进行重写。
 重要的一点是:如果下面有一个相同的配置,则下面的配置会覆盖上面的配置 。
即 如 果 下 面 还 有 <Directory></Directory> , 则 覆 盖 该 上 面 的 <Directory></
Directory> 配置。 在该文件的下一段<Directory></Directory>中可以对相关配置进
行修改。
 指定将会配置权限的根目录:在首<Directory>标签内设置根目录,以便下面
对 该 根 目 录 的 访 问 呢 权 限 进 行 设 置 。 如 这 里 的
,设置这个根目录是因为默认将
Web 服务器的根目录设置为 htdocs 下,所以需要对该根目录的访问权限进
行设置。如果没有对哪个根目录进行允许访问的设置,那么 Web 浏览器是
无 法 访 问 的 ( 403 Forbidden 无 权 限 访 问 错 误 提 醒 ) , 因 为 在 第 一 段 的
<Directory>中已经严格地拒绝了所有的访问。
 是否允许重写 AllowOverride(只针对<Directory>中指定的根目录生效):
None 表示不允许,All 表示允许所有。
 配置是否允许用户访问该 Web 服务器根目录(只针对<Directory>中指定的
根目录生效):

 Order allow,deny:表示访问权限先看 allow 允许什么,再看 deny 不允许


什么。
 Allow from all:表示允许所有用户可以访问该根目录,此时,当任何用
户访问 http://localhost/news.php 时就能访问了。
 Deny from all:表示拒绝所有用户访问该根目录,此时,当任何用户访
问(http://localhost/news.php)时会出现 403 Forbidden 的没有权限的
错误提示。实际应用中,作为 apache 服务器的管理员,应该在这里拒
绝所有用户的访问(Deny from all),因为不同的应用程序应该有其自
己的访问根目录,而不能访问 Web 服务器该根目录下别人的内容,所
以需要再继续指定针对某个应用程序的根目录下的访问权限。
 如果希望部分 ip 可以访问,则可以写成:

7.3.2.2 加载 apache 的 rewrite 机制,只有加载 apache 的 rewrite 机制后,才能使用 apache


的 rewrite 机制:
 在 apache/conf/下打开 httpd.conf 文件。
 找到如下:

 默认情况下是关闭的,即前面有一个#号,删除它,便可以开启它。即:

 注意:如果低版本的 apache 没有这句话,则在“LoadModule”区域的最后一行追


加这句话。
LoadModule rewrite module modules/mod_rewrite.so
 必须重启 apache,才能生效。
 为了确保的确启用了该机制,可以在一个 php 文件中测试一下:
<?php phpinfo(); ?>
可以查看到在 Loaded Modules 中存在“mod_rewrite”这个模块,说该机制已经启
用。

7.3.2.3 关联 ip 和域名:
 打开 c:\windows\system32\drivers\etc 下的 hosts 文件。
 添 加 虚 拟 主 机 中 添 加 你 的 ip 和 域 名 对 应 关 系 , 如 下 可 以 添 加 127.0.0.1
www.hsp.com,这样就配置了一个 ip 为 127.0.0.1 和域名为 www.hsp.com 的对应
关 系 的 虚 拟 主 机 。 这 样 就 可 以 使 用 域 名 了 , 而 不 用 总 是 使 用 localhost 或
127.0.0.1。即网址可变为:http://www.hsp.com/。备注:如果要访问局域网中其
他机器,则改成其他机器的 ip。

7.3.2.4 启用虚拟主机:
 在 apache/conf/extra 下打开 httpd.conf 文件,去掉前面的#号:

 重启 apache。
7.3.2.5 配置虚拟主机---httpd-vhosts.conf 文件:
 在 apache/conf/extra 下打开 httpd-vhosts.conf 文件。
 找到<VirtualHost *:80></VirtualHost >这段话:

 在这段话下面写一段<VirtualHost *:80></VirtualHost>来覆盖上面这段话,或者直
接将这段话复制沾粘到下一面直接进行修改:
 DocumentRoot:用来配置虚拟主机的根目录,可自行修改。比如这里设置
为 C:/myeenv/apache/htdocs/static3,也可以设置任何的目录,比如:d:/
static3。
 ServerName : 用 来 设 置 虚 拟 主 机 所 使 用 的 服 务 器 名 字 , 在 c:\windows\
system32\drivers\etc 的 hosts 文件中找到已经存在的 ip 和域名,比如之前我
们配置的 www.hsp.com,所以,就在这里 ServerName 处写 www.hsp.com。
经 过 这 样 的 配 置 , 那 么 , 网 址 虚 拟 主 机 服 务 器 名 字 ( http://
www.hsp.com/ )将对应到虚拟主机的根目录( C:/myeenv/apache/htdocs/
static3/)。
 再来配置虚拟主机所设置根目录的 Web 浏览器的访问权限:在<VirtualHost
*:80></VirtualHost> 段 最 后 , </VirtualHost> 尾 标 签 之 前 , 添 加 一 段
<Directory></Directory> , 这 样 可 以 覆 盖 apache/conf/httpd.conf 文 件 中 的
<Directory></Directory>,但仅限于该域名(ServerName),这意味着进一
步限制了指定用户的权限,即对于指定的域名只能访问指定的根目录,而
不能访问其他根目录。
#告诉<Directory>将要配置的虚拟主机的根目录,即上面 DocumentRoot 设置
的根目录。
<Directory "C:/myeenv/apache/htdocs/static3">
# 允许 所有用户访问 Web 服务器根 目录 ( 备注 :由于 DocumentRoot 和
ServerName 的设置,允许用户通过域名来访问对应的根目录)
Allow from all
# Options+indexes 当根目录不在 htdocs 下,即不放在 apache 目录下(比如
将上面的根目录配成 d:/static3),则该语句表示当访问 www.hsp.com 时,
将显示根目录下的所有文件列表,如果不写该句话,则不显示并出现 403
Forbidden 的没有权限的错误提示。但如果根目录在 htdocs 下,则不管是否
写这句话,都会显示根目录下的所有文件列表。在发布项目后一般是需要
禁用的,因为不希望别人看到目录下的列表,即不写该语句,或在该语句
前加上#号注释掉。
#Options+indexes
#启用 apache 的 rewrite。
AllowOverride all
</Directory>
 然后重启 apache,如配置错了,重启时会报错。

 更进一步,有时候有这样的情况,在该根目录下,还有 aa 文件夹和 bb 文件夹,


你允许用户通过 Web 浏览器可以访问该根目录以及其下除了 bb 文件夹以外的所
有内容,这样可以通过再在下面写一个<Directory></Directory>段来禁用 bb 文件
夹。但特别需要说明的是:虽然下面的配置拒绝了 Web 浏览器去访问 bb 根目录,
它是不然别的用户去访问该根目录,但是本地(即本服务器计算机自己)所有
目录之间都是可以相互访问的(比如 aa 下的某个文件去调用 bb 下的某个文件
等),不受任何访问权限的限制。
<VirtualHost *:80>
DocumentRoot "C:/myenv/apache/htdocs/static3"
ServerName www.hsp.com
ErrorLog "logs/dummy-host2.somenet.com-access.log" common
<Directory "C:/myenv/apache/htdocs/static3">
Allow from all
#Options+indexes
Allowoverride all
#rewrite 规 则 , 见 其 后 的 说 明 , 该 rewrite 针 对 的 是 C:/myenv/apache/htdocs/
static3 根目录,即该目录及其子目录和所有文件。
</Directory>
<Directory "C:/myenv/apache/htdocs/static3/bb">
Deny from all
#Options+indexes
Allowoverride all
#rewrite 规 则 , 见 其 后 的 说 明 。 该 rewrite 针 对 的 是 C:/myenv/apache/htdocs/
static3/bb"根目录,即在 bb 根目录中将优先使用这个文件的规则。
</Directory>
</VirtualHost>

7.3.2.6 编写 rewrite 规则:


 在根目录(C:/myeenv/apache/htdocs/static3/)下创建一个文件(.htaccess),
这个文件没有文件名,无法在资源管理器中直接创建,可以通过打开 notepad++
来新建该文件就可以了。该文件用于编写重写规则。需要注意的是,.htaccess 文
件是针对本根目录的,即本目录以及其下的所有子目录和文件的。如果 static3/
还有子目录,且如果在子目录下再创建一个 .htaccess 文件来配置该子目录的
rewrite 规则,该文件针对该子目录具有更高的优先级。
 在.htaccess 文件中:
#<IfModule> 收 尾 标 签 用 于 判 断 是 否 已 经 启 用 apache 的 rewrite 机 制 , 即 在
apache/conf/httpd.conf 中 是 否 已 经 启 用 apache 的 rewrite 机 制 :
。 加 了
<IfModule>即实现先判断是否已经启用了 rewrite 机制,如果启用则执行下面的
配置,否则不执行下面的配置。而如果不写<IfModule>,那当未启用 rewrite 机
制时,遇到下面这些语句自然就会报错。
<IfModule rewrite_module>
#启用
RewriteEngine On
#通过正则表达式方法编写下面语句,将 news-id3.html 重写成 news.php?id=3,
这里的 3 可以是任何的数字,\d+代表可以是任何的数字。
RewriteRule news-id(\d+)\.html$ news.php?id=$1
#RewriteRule 可以配多个,即同时写多个 rewrite 规则,一个规则为一行。匹配
优先级从上到下。
</IfModule>
代码即为:
<IfModule rewrite_module>
RewriteEngine On
RewriteRule news-id(\d+)\.html$ news.php?id=$1
#RewriteRule。。。。可写其他规则
</IfModule>

 这样,当需要访问根目录下的 news.php 文件时,在浏览器中却输入不用再输入


http://www.hsp.com/news.php?id=3,而只需要输入:

,就会连到 http://www.hsp.com/

news.php?id=3。所以,实际上只有且访问的也是 news.php 这个 php 文件,并不


存在 news-id3.html 文件,所有称为伪静态。
 备 注 : 很 多 时 候 , 可 以 不 用 那 么 麻 烦 , 可 以 不 用 创 建 .htaccess 文 件 来 编 写
rewrite 规则,而直接把 rewrite 规则写到 httpd-vhosts.conf 文件的<Directory></
Directory>的最后,即</Directory>之前,效果也是一样的。

8 自动定期删除文件(如果产生海量文件):
8.1 针对 windows 系统:
 在应用程序根目录下建立一个 php 文件(这里比如是 c:\myenv\apache\htdocs\static3\),
比如:clear.php,并编写如下代码来指定需要删除哪些文件:
<?php
//代码:遍历指定的某些目录,找出已经过期的文件。
//unlink("news-id100.html"); //删除这些文件
?>
 在 apache/bin/下创建一个.bat 文件,比如:mybat.bat,并在该文件中写入如下内容:
"C://myenv\\apache\\bin\\ab.exe" -n 1 - c 1 http://www.hsp.com/clear.php
备 注 : 以 上 语 句 代 表 当 执 行 mybat.bat 时 , 会 用 ab.exe 模 拟 执 行 访 问 clear.php 。 其 中 ,
apache\bin\ab.exe 的路径根据实际来写。
 此时,如果双击该 bat 文件,就可以删除在 clear.php 中指定的文件。但我们按照如下方法,
可以自动定期产生设置的文件:控制面板->任务计划->添加任务计划->点击下一步->点击浏
览->选择创建的 mybat.bat->可以修改任务名称,在执行这个计划中选择希望按照什么频率
执行该任务,比如每天->选择执行该任务的开始时间以及开始日期->输入密码(用户的登录
密码,以确保系统可以自动执行任务)->点击完成。这样,系统就会按照设置的频率自动
定期删除设置的文件。备注:该文件也可以在属性中修改定期时间等相关选项。
8.2 针对 linux 系统:
 Linux 有 crontab。通过.sh 文件(shell 编程)来实现。

9 真静态实现页面静态化实例—新闻管理系统

建立数据库
/*创建表格*/
CREATE DATABASE spdb1;
USE spdb1;
CREATE TABLE news(
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(128) NOT NULL,
content VARCHAR(256) NOT NULL,
filename VARCHAR(32)) /*记录静态页面的名字*/
ENGINE=MyISAM;

/*创建一些测试数据*/
INSERT INTO news(title,content) VALUES('hello1','beijing nihao');
INSERT INTO news(title,content) VALUES('hello2','sichuan nihao');
new_list.php
<?php
//查询数据库,一般使用 SqlHelper.class.php,这里自己写一下代码
$conn = mysql_connect("localhost","root","root") OR die("MySQL connet Falure!");
mysql_select_db("spdb1",$conn); //如果不使用$conn,则 php 会使用最后一个连接,好习惯是加上自
己需要的连接,而且速度也相对更快一些,因为 php 不用去往上找最近的那个连接。
//mysql_query("set names uft8");
$sql = "SELECT * FROM news";
$res = mysql_query($sql);

header("content-type:text/html; charset=utf-8");
echo "<h1>News List</h1>";
echo "<a href='add_news.html'>add news</a><hr/>";
echo "<table><tr><td>id</td><td>title</td><td>see details</td></tr>";
while($row = mysql_fetch_assoc($res)){
echo "<tr><td>{$row['id']}</td><td>{$row['title']}</td><td><a href='news_id{$row['id']}.html'>see
details</a></td><td><a href='news_update. php?id={$row['id']}'>update</a></td><td><a
href='news_delete.php?id={$row['id']}'>delete</a></td></tr>";
echo "</table>";
}
mysql_free_result($res);
mysql_close($conn);
?>
add_news.html
表单文件
action 到 newsAction.php

update_news.html
表单文件
action 到 newsAction.php

template.tpl
<html>
<head>
<title>%title%</title>
</head>
<body>
<h1>%title%</h1>
<hr />
<pre>%content%</pre>
</body>
</html>
newsAction.php
<?php
header("content-type:text/html; charset=utf-8");

//设计一个替换的函数
function replace($row,$title,$content){
$row=str_replace("%title%",$title,$row);
$row=str_replace("%content%",$content,$row);
return $row;
}

$oper=$_REQUEST['oper']; //通过在表单中添加一个隐藏域设置 value 来确认是 INSERT、UPDATE 还是


DELETE,对于 INSERT,name=oper,value=add;对于 UPDATE,value=update;对于 DELETE,通过<a>中
GET 出 name 还是=oper,值=delete。

//连接数据库(也可使用 SqlHelper.class.php 来简化),先将数据 insert 到数据库


$conn = mysql_connect("localhost","root","root") OR die("MySQL connet Falure!");
mysql_select_db("spdb1",$conn); //如果不使用$conn,则 php 会使用最后一个连接,好习惯是加上自
己需要的连接,而且速度也相对更快一些,因为 php 不用去往上找最近的那个连接
$title=$_POST['title']; //新闻标题
$content=$_POST['content']; //新闻内容

if($oper=='add'){
$sql="INSERT INTO news (title,content) VALUES ('$title','$content')";
if(mysql_query($sql,$conn)){ //如果 insert 成功,则可以获得该条数据的 id,这样就可以设计 html 页
面的文件名了。
$id=mysql_insert_id();
$html_filename="news_id".$id.".html";
$fp_tmp=fopen("template.tpl","r"); //不能以 w 方式打开,不然文件内容会被清空。
$fp_html_file=fopen("$html_filename","w");

//用于 html 静态文件中可以识别中文。


$my_header="<head><meta http-equiv='content-type' content='text/html; charset=utf-8' /></head>";
fwrite($fp_html_file, $my_header);

//逐行读取模板文件并写入 html 文件,在通配符的地方替换成实际数据。


while(!feof($fp_tmp)){ // 当文件指针达到文件结尾 feof()则返回 TRUE。
$row=fget($fp_tmp); //按行读取
$new_row=replace($row,$title,$content);
fwrite($html_filename, $new_row);
}
fclose($fp_tmp);
fclose($fp_html_file);
}
mysql_close($conn);

} elseif($oper=='update'){
$id=$_POST['id'];
$sql="update news set title='$title', content='$content' where id=$id";
if(mysql_query($sql, $conn)){
$html_filename="news_id".$id.".html";
unlink($html_filename); //删除该 html 文件,再重新通过 insert 的方法创建 html 文件。
$sql="INSERT INTO news (title,content) VALUES ('$title','$content')";
if(mysql_query($sql,$conn)){ //如果 insert 成功,则可以获得该条数据的 id,这样就可以设计 html
页面的文件名了。
$id=mysql_insert_id();
$html_filename="news_id".$id.".html";
$fp_tmp=fopen("template.tpl","r"); //不能以 w 方式打开,不然文件内容会被清空。
$fp_html_file=fopen("$html_filename","w");

//如何防止浏览器缓存页面: (1) Express: -1; (2) Cache-Control: no-cache; (3)Pragma: no-cache.


$my_header="<head><meta http-equiv='content-type' content='text/html; charset=utf-8' />
<meta http-equiv='Cache-Control' content='no-cache' />
<meta http-equiv='Expires' content='-1' />
<meta http-equiv='Pragma' content='no-cache' />
</head>";
fwrite($fp_html_file, $my_header);

//逐行读取模板文件并写入 html 文件,在通配符的地方替换成实际数据。


while(!feof($fp_tmp)){ // 当文件指针达到文件结尾 feof()则返回 TRUE。
$row=fget($fp_tmp); //按行读取
$new_row=replace($row,$title,$content);
fwrite($html_filename, $new_row);
}
fclose($fp_tmp);
fclose($fp_html_file);
}
mysql_close($conn);
}

} elseif($oper=='delete'){

}
?>
总结:
 为了减少对数据库的访问量,且希望静态页面的数据可以实时性,我们会选择使用真静态技术,
真静态技术也利于 seo。对于有海量 id 的网站,会产生海量的 html 文件,因为它是在 INSERT 时
同时产生 html 文件的,需要注意的是真静态还是会在 insert 和创建 html 间产生一些延时。带来
的问题就是(1)磁盘占用多,(2)查询海量文件同样有速度问题。对于(2)一个解决方法是
根据 id 产生的时间存入不同的文件夹中,这样可以有针对的访问不同的文件夹来加快查询文件的
速度,但是无法解决磁盘占用多的问题。
 为了减少对数据库的访问量,也可以使用 php 自带 ob 缓存技术,但是它会产生被更新数据的时
间滞后,因为它是在 SELECT 时产生 html 文件的,数据在数据库更新后无法改变和 html 文件,所
以只能通过设置一个过期时间来解决。但也正是由于它在 SELECT 时而不是在 INSERT 时产生 html
文件,所以它产生的 html 文件更符合实际需求,不会产生访问量少的 html 文件,但是需要注意
的是,随着时间和访问量的推进,最终它还是会产生海量 html 文件。
 伪静态技术的目的是为了利于 seo,但还是要访问数据库,所以我们可以结合 php 自带 ob 缓存技
术和伪静态技术。
 而为了解决海量 html 的问题,特别是那些对早期数据访问量很低的情况,比如新闻、对账单等,
用户一般只会查询最近的信息,我们可以定期手动,或通过编程来定期自动删除较早的 html 文件,
具体手动还是自动,取决于实际应用情况。

 一些建议:
 如果网站数据的实时性要求很高,UPDATE 很平凡,比如股票价格,就不适合使用页面静态
化技术。
 如果网站访问量较小,也没有必要使用页面静态化技术。
 如果数据项目(id)不多,但访问频率很高,就要使用真静态技术,比如新浪新闻,一天没
有多少新闻,但新闻访问量会非常高。
 如果数据项目(id)海量,如果使用真静态技术就会产生海量 html,建议使用伪静态技术。
 设计方案 1 – 真静态:
 对象:以查询 SELECT 为主,修改 UPDATE 较少的数据,且用户更关心近期的数据。
 方案:(1)首先使用真静态以实现减少数据库访问以及 html 文件内容的实时性。(2)如果
会产生海量文件,就定期删除较早的文件,文件按照数据本身的新旧日期(也可以按照 id 的
数量分文件夹)存放在不同的文件夹内以加快访问速度。( 3)和真静态方案不同的是,此
时在查询时需要先要判断 html 文件是否存在,如果不存在则使用 insert 时的方法创建。
 设计方案 2—php 自带 ob 缓存:
 对象:以查询 SELECT 为主,修改 UPDATE 较少的数据,且用户更关心近期的数据。
 方案:(1)首先使用 php 自带缓存技术在 SELECT 时创建 html 文件。(2)当发生 update 时,
查询 html 文件是否存在,如果存在则更新该 html 文件。(3)如果会产生海量文件,就定期
删除较早的文件,文件按照数据本身的新旧日期(也可以按照 id 的数量分文件夹)存放在不
同的文件夹内以加快访问速度。

You might also like