实现静态化

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现静态化相关的知识,希望对你有一定的参考价值。

一、内容回顾

实现静态化的方式:

真静态:使用ob缓存方式,使用模板替换,

ob_start();//开启o b缓存

ob_clean();//清除o b缓存里面的数据,并不关闭ob缓存。

ob_end_clean();//清除ob 缓存里面的数据,并关闭ob缓存

ob_flush();//把ob缓存里面的数据移动(刷新)到程序缓存,不关闭ob缓存。

ob_end_flush();//把ob缓存里面的数据移动到程序缓存,并关闭ob缓存。

ob_get_contents();//获取ob缓存里面的内容。

?

?

在判断缓存有效期:生成的静态页面最后的修改时间戳+缓存时间>当前时间戳

filemtime($filename)+300>time();

?

ab.exe

ab.exe –n 请求的总的次数 -c并发数 测试的地址。

mpm:多路处理模块(apache处理并发的方式)主要是预派生模型,工作者模型,winnt模型。

查看当前apache的mpm:httpd.exe –l

?

?

在程序缓存里面,存储的是,先存储头信息,然后,是页面的主体信息。存储了主体信息,再存储(修改)头信息,则会出现警告错误。

?

二、如何配置缓存:

把一些更新不是很频繁的数据,缓存到本地。下次再请求网站的时候,则直接从本地取出,无需从服务器里取出。

基本图示:

技术分享

1、缓存的原理:

第一次访问头信息:

技术分享

技术分享技术分享技术分享

第二次访问:

技术分享技术分享技术分享技术分享技术分享

技术分享技术分享技术分享

?

2、如何配置缓存

?

(1)打开apache的主配置文件(httpd.conf)开启缓存模块

打开apache的expires扩展,利用该扩展控制图片,css,html等文件控制缓存是否缓存,及缓存声明周期。

技术分享

(2)配置选项设置

?

ExpiresActive On //开启缓存设置

//具体的针对文件类型设置缓存规则。

ExpiresDefault "<base> [plus] {<num> <type>}*"//默认设置
ExpiresByType type/encoding "<base> [plus] {<num> <type>}*"//针对不同文件类型进行设置。

?

技术分享技术分享技术分享技术分享技术分享

?

?

(3)具体的配置步骤:

为了测试:新建一个虚拟主机:

技术分享

?

?

技术分享技术分享技术分享

?

思考:如果我们想要对js文件配置缓存周期,如果设置文件的类型。

可以在页面中引入某个文件,比如:

技术分享

通过浏览器刷新该页面,查看头信息:

?

技术分享

expiresbytype application/javascript "access plus 10 days"

?

3、可以针对某些文件,不让他缓存,始终从服务器中获取内容。

比如案例:不缓存gif文件。

思路,打开apache主配置文件,中header模块,配置该选项:cache-control:no-store,must-revalidate,

具体 的步骤:

(1)开启header模块。

技术分享

(2)具体的配置:思路是针对gif格式的文件。

在虚拟主机里面进行如下配置:

技术分享技术分享技术分享技术分享技术分享

(3)效果:

技术分享

三、配置压缩

技术分享

如何查看浏览器支持的压缩格式:可以通过请求头信息里面accept-encoding选项查看浏览器支持的压缩格式。

技术分享

?

如常见的gzip压缩,deflate压缩,compress压缩以及google、chrome正在推的sdcn压缩。

?

具体的配置步骤:

(1)在apache的主配置文件中,开启压缩配置,apache默认是deflate压缩。

技术分享

(2)在虚拟主机里面配置。

技术分享

(3)开始测试:

文件本身的长度:

技术分享

压缩前的长度:

技术分享

?

压缩后的长度:

技术分享

?

四、完成一个真静态的一个案例

(通过新闻列表,单击新闻详情,跳转到具体的新闻页面,该具体的新闻页面完成真静态)

原理图:

技术分享

思路:主要有如下几个页面。

addnews.html:新闻添加页面(有表单)

action.php:新闻处理页面(比如添加,修改,删除)

index.php:新闻列表页面

newsinfo:新闻详情页面。

?

(1)新建一个新闻的表:

技术分享技术分享技术分享

?

?

?

?

?

?

(2)新建一个添加新闻的页面:

技术分享

(3)新建一个action.php页面完成入库

技术分享

(4)完成首页(列表页面)

<?php

$conn = mysql_connect("localhost",‘root‘,‘root‘);

mysql_query("use php");

mysql_query("set names utf8");

?

$sql="select id,title from news";

$list=array();

$res = mysql_query($sql,$conn);

while($row=mysql_fetch_assoc($res)){

$list[]=$row;

}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">

<head>

<title>新建网页</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<meta name="description" content="" />

<meta name="keywords" content="" />

<script type="text/javascript">

?

</script>

?

<style type="text/css">

</style>

</head>

<body>

<h1>新闻列表页面</h1>

<table width="500" border="1">

<tr><td>新闻标题</td><td>新闻详情</td><td>操作</td></tr>

<?php foreach($list as $v){?>

<tr><td><?php echo $v[‘title‘]?></td><td>新闻详情</td><td>操作</td></tr>

<?php }?>

</table>

</body>

</html>

(5)在列表页面,给新闻详情添加超级链接

技术分享

(6)给新闻详情页面生成静态页面。

<?php

//接收传递过来的id

$id = $_GET[‘id‘]+0;

//给对应的静态页面命名

$filename = "news_id".$id.‘.html‘;

//echo $filename;

//添加判断

if(file_exists($filename) && filemtime($filename)+300>time()){

//echo ‘99999999‘;

include $filename;exit;

}

$conn = mysql_connect("localhost",‘root‘,‘root‘);

mysql_query("use php");

mysql_query("set names utf8");

$sql="select title,content from news where id = $id";

$res = mysql_query($sql,$conn);

$row=mysql_fetch_assoc($res);

ob_start();

?>

?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">

<head>

<title>新建网页</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<meta name="description" content="" />

<meta name="keywords" content="" />

<script type="text/javascript">

?

</script>

?

<style type="text/css">

</style>

</head>

<body>

<h1>新闻的详情页面</h1>

<h3><?php echo $row[‘title‘]?></h3>

<hr>

<div><?php echo $row[‘content‘]?></div>

</body>

</html>

<?php

$str = ob_get_contents();

file_put_contents($filename,$str);

?>

?

缺点:该新闻详情页面,即使没有修改,也是每隔5分钟要重新生成一次。可以做成,只要新闻没有修改,则一直使用静态页面,如果新闻更改了则立刻重新生成一个对应的静态页面。

五、使用模板替换技术来完成真静态:

?

思路:

在添加新闻的时候,生成对应的静态页面。

在修改新闻的时候,重新生成对应的静态页面。

让新闻列表页面的链接直接链接对应生成的静态页面。

原理图:

技术分享

具体的步骤;

(1)新建一个模板文件,tpl.html:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">

<head>

<title>新建网页</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<meta name="description" content="" />

<meta name="keywords" content="" />

<script type="text/javascript">

?

</script>

?

<style type="text/css">

</style>

</head>

<body>

<h1>新闻的详情页面</h1>

<h3>%title%</h3>

<hr>

<div>%content%</div>

</body>

</html>

(2)修改action.php页面

if($act==‘add‘){

//接收表单提交过来数据

$title = $_POST[‘title‘];

$content = $_POST[‘content‘];

$sql="insert into news(title,content) values(‘$title‘,‘$content‘)";

$res = mysql_query($sql,$conn);

$id = mysql_insert_id($conn);

if(!$id){

die("添加失败");

}

//完成生成静态页面

//给对应的静态页面命名

$filename = ‘news_id‘.$id.‘.html‘;

//打开模板文件

$tpl_ph=fopen(‘tpl.html‘,‘r‘);

//创建对应的静态页面。

$file_ph=fopen($filename,‘w‘);

//完成替换

//feof()函数,返回文件指针是否到文件的末尾,如果到则返回的真。

while(!feof($tpl_ph)){

$row=fgets($tpl_ph);//fgets()函数是读取一行内容

$row=str_replace(‘%title%‘,$title,$row);//str_replace()该函数返回替换之后的结果

$row=str_replace(‘%content%‘,$content,$row);

fwrite($file_ph,$row);//把替换之后的内容,写入到$filename文件中。

}

fclose($tpl_ph);//关闭文件指针

fclose($file_ph);//关闭文件指针

echo ‘添加成功‘;

echo "<a href=‘index.php‘>返回首页</a>";

}

(3)修改新闻的列表页面,把新闻的详情链接修改成对应的静态页面。

?

技术分享

?

(4)修改新闻时则重新生成对应的静态页面。

(3)删除新闻的时候,则要删除对应的静态页面。unlink

?

缺点:

(1)如果新闻比较多,则生成的静态页面比较多,应该采用分层存储静态页面。

(2)还没有达到全站静态化,我们应该让首页面生成静态页面,达到全站静态化。

(3)把生成的静态页面的路径添加到数据库的字段中。

?

六、使用模板替换技术完成真静态,进一步完善

一个项目有前台和后台,全站静态化是针对的前台,

?

案例规划:

技术分享技术分享技术分享技术分享技术分享

?

?

?

(1)复制上午的项目(demo1),把文件移动到admin目录中。

目标:创建生成的静态页面的路径,创建数据库中filename字段的存储路径

?

<?php

$act = isset($_GET[‘act‘])?trim($_GET[‘act‘]):"";

$conn = mysql_connect("localhost",‘root‘,‘root‘);

mysql_query("use php");

mysql_query("set names utf8");

//添加新闻

if($act==‘add‘){

//接收表单提交过来数据

$title = $_POST[‘title‘];

$content = $_POST[‘content‘];

$sql="insert into news(title,content) values(‘$title‘,‘$content‘)";

$res = mysql_query($sql,$conn);

$id = mysql_insert_id($conn);

if(!$id){

die("添加失败");

}

$dir = date("Ym/d");

$file="news_id".$id.‘.html‘;//表示生成的静态文件的名称

$dir_path="../a/".$dir;

//要判断$dir_path目录是否存在,如果不存在则创建。

if(!is_dir($dir_path)){

mkdir($dir_path,0777,true);

}

$filename =$dir_path.‘/‘.$file; //生成的静态文件的完整路径;

$filename_path="./a/".$dir.‘/‘.$file;//存储到数据库filename字段中的静态页面的路径:

//打开模板文件

$tpl_ph=fopen(‘tpl.html‘,‘r‘);

//创建对应的静态页面。

$file_ph=fopen($filename,‘w‘);

//完成替换

//feof()函数,返回文件指针是否到文件的末尾,如果到则返回的真。

while(!feof($tpl_ph)){

$row=fgets($tpl_ph);//fgets()函数是读取一行内容

$row=str_replace(‘%title%‘,$title,$row);//str_replace()该函数返回替换之后的结果

$row=str_replace(‘%content%‘,$content,$row);

fwrite($file_ph,$row);//把替换之后的内容,写入到$filename文件中。

}

fclose($tpl_ph);//关闭文件指针

fclose($file_ph);//关闭文件指针

?

//把生成的对应静态页面的路径存储到数据库里面的filename字段

$sql="update news set filename=‘$filename_path‘ where id=$id";

$res = mysql_query($sql);

$num = mysql_affected_rows($conn);

if(!$num){

die("失败");

}

echo ‘添加成功‘;

echo "<a href=‘index.php‘>返回首页</a>";

}

?>

?

(2)完成后台的首页。

技术分享技术分享技术分享

?

(3)新建一个makehtml.php页面完成,前台首页的生成。

?

<?php

$conn = mysql_connect("localhost",‘root‘,‘root‘);

mysql_query("use php");

mysql_query("set names utf8");

?

$sql="select id,title,filename from news";

$list=array();

$res = mysql_query($sql,$conn);

while($row=mysql_fetch_assoc($res)){

$list[]=$row;

}

ob_start();

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">

<head>

<title>新建网页</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<meta name="description" content="" />

<meta name="keywords" content="" />

<script type="text/javascript">

?

</script>

?

<style type="text/css">

</style>

</head>

<body>

<h1>新闻列表页面</h1>

?

<table width="500" border="1">

<tr><td>新闻标题</td><td>新闻详情</td><td>操作</td></tr>

<?php foreach($list as $v){?>

<tr><td><?php echo $v[‘title‘]?></td><td><a href="<?php echo $v[‘filename‘]?>">新闻详情</a></td><td>操作</td></tr>

<?php }?>

</table>

</body>

</html>

<?php

$str = ob_get_contents();

file_put_contents("../index.html",$str);

ob_clean();

echo "首页已经已经生成 <a href=‘../index.html‘>返回前台首页</a>";

?>

(4)测试效果:

技术分享

?

七、真静态的优缺点说明:

优点: 1. 速度快 2. 安全性高 3. 利于seo

缺点:就是占有磁盘空间., 如果过大,对磁盘响应速度有影响

在什么情况下,建议不要使用真静态

  1. 页面的数据更新频繁,最好不要使用真静态(比如股票,基金,等实时报价系统)
  2. 会生成海量页面(比如大型论坛 bbs ,csdn)
  3. 查询该页面一次后,以后再也不查询该页面.
  4. 不愿意被搜索引擎抓取的页面.
  5. 访问量小的页面.

八、伪静态,使用正则匹配来完成伪静态。

实现的方式:使用正则匹配,通过apache的rewrite机制。

?

基本图示:

技术分享

具体的步骤:复制上午的案例dome改成demo3.

(1)打开index.php页面把新闻详情的链接改成<a href=‘newsinfo.php/news_id88.html‘>新闻详情</a>

技术分享

(2)修改newsinfo.php页面。

<?php

$path_info = $_SERVER[‘PATH_INFO‘];//获取到 地址中:news_id1.html

$patt = ‘/news_id(\\d{1,3})\\.html$/‘;

preg_match($patt,$path_info,$a);//$a用于存储匹配到的内容。

$id = $a[1];

$conn = mysql_connect("localhost",‘root‘,‘root‘);

mysql_query("use php");

mysql_query("set names utf8");

$sql="select title,content from news where id = $id";

$res = mysql_query($sql,$conn);

$row=mysql_fetch_assoc($res);

?>

?

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">

<head>

<title>新建网页</title>

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<meta name="description" content="" />

<meta name="keywords" content="" />

<script type="text/javascript">

?

</script>

?

<style type="text/css">

</style>

</head>

<body>

<h1>新闻的详情页面</h1>

<h3><?php echo $row[‘title‘]?></h3>

<hr>

<div><?php echo $row[‘content‘]?></div>

</body>

</html>

?

九、使用rewrite机制,完成伪静态。

1、rewrite机制的使用原理

技术分享

2、rewrite机制的具体配置:

(1)打开apahce的主配置文件(httpd.conf),开启rewrite模块。

技术分享

(2)为了测试,新建一个虚拟主机,使用上午创建的。

技术分享

(3)入门案例:请求abc.html转换成请求123.php,在虚拟主机目录下面建立该两个文件。

具体的配置内容:

技术分享

?

3、虚拟主机里面常用的配置。

(1)#配置是否显示文件目录:[indexes|none]

Options indexes FollowSymLinks //配置显示文件目录,如果没有配置欢迎页面。

技术分享

?

如果配置成 options none

技术分享

(2)配置错误跳转页面。主要防止用户请求的页面不存在,如果用户访问的页面不存在,则给一个友好的提示。

技术分享

技术分享

(3)配置欢迎页面,也就是访问域名时默认执行页面。

?

#配置网站的欢迎页面:

DirectoryIndex abc.html

?

技术分享

?

4、完成一个案例:

比如请求的url

http://www.abc.com/news-music-id100.html

转换成请求:news.php?type=music&id=100页面,或news.php?type=sport&id=100

具体的配置:

技术分享

效果:

技术分享

5、可以新建一个.htaccess文件,具体的内容可以在该文件进行配置。

要注意:要使该文件有效,则必须在虚拟主机里面设置。AllowOverride All

技术分享技术分享技术分享

(1)新建一个.htaccess文件,

可以通过编辑器来另存为创建一个.htaccess文件。

就可以把一些配置选项在里面完成。

(2)在该文件中定义重写规则

技术分享

?

6、通过使用rewrite机制完成一个防盗链案例。

?

主要原理:利用referer头信息,

技术分享技术分享技术分享

?

具体的配置:

技术分享

以上是关于实现静态化的主要内容,如果未能解决你的问题,请参考以下文章

抽象类和接口总结回顾

aspnetcore 实现简单的伪静态化

php利用ob缓存机制实现页面静态化方法全解

PHP实现页面静态化

MVC 页面静态化

静态化 - 真静态技术