1、介绍
(1)缓存介绍
1)浏览器缓存:
是保存在浏览器端的缓存,这个缓存我们没有办法控制。在360等卫士的清理下,缓存的时间也是没有保证的。这个缓存默认是保存多少?根据浏览器的不同有所不同。我们可以设置web服务器通知浏览器进行保存!
2)PHP端的缓存:
①:程序缓冲:这是一个PHP自带的缓存机构,我们(程序员)是没有办法控制的。只能知道有这么一个东西,他在我们的操作中起着重要的作用。
②:ob缓冲:这个比程序缓存高级一点,高级的原因是我们可以操作它!在它的上面完成我们静态化的工作。也可以根据你的想像力,实现它可以实现的功能。
ob缓冲,可以有多个,可以没有。程序缓冲,是必须有的。ob缓冲可以进行任意的操作,实现对数据流的处理。
(2)静态化介绍
由ob缓冲生成的静态化概念,叫做真静态化。
真静态就是把PHP动态生成的内容,生成HTML文件。这个时候由于PHP输出的内容都在ob缓冲里面,我们可以获得里面的,保存成一个HTML文件。
真静态的优化:就是可以提升访问量,HTML页面的性能比PHP好。也是由于HTML页面,可以被搜索引擎收录!
由于真静态的概念,就出现了伪静态的概念。
伪静态就是由web服务器实现的功能,从URL的访问方式来看,就是访问一个静态的页面。通过WEB服务器的路由规则,把访问的页面,重新定向到PHP动态页面,这就是伪静态。
整个搜索引擎对HTML页面,也就是静态页面,非常喜欢。收录的非常的快。
搜索引擎:百度,搜狗,360。
如果你的内容要在搜索引擎里面被找到,你的网页内容必须提前被搜索引擎收录。没有收录的是没有办法搜索到的。
使用真静态的时候:是真的有一个index.html页面,可以被直接访问到。
使用伪静态的时候:就真的没有一个index.html页面,这个时候,通过web服务器的路由规则,重新定向到一个你想定向的网页。比如search.php,比如index.php也可以。定向到谁,能定向到谁,根据你的想像力。
(3)压力测试软件介绍
1)找到这个已经安装好的软件:在Apache/bin/
下有一个ab.exe,这个就是测试软件,Linux上面安装成功,也是有这个软件的。而且使用方式一模一样 。
2)使用方式,进入到:Apache/bin/
目录下,查看帮助信息:ab --help
其中需要知道的是:
-n requests:总的请求数,就是一共要发出去的请求
-c concurrency:并发请求数,就是一次性发出去的请求。
3)使用方法:ab -n 200 –c 50 http://域名/path
4)说明一下参数
有一个值:
Requests per second : 105.72 [#/sec] (mean) //每秒请求的次数【QPS|RPS】
这个点是我们非常重要的数据,这个数据越高越好。每个程序执行耗费的时间越短,这个就越高。
你要告诉别人网站的性能,就告诉它QPS是多少。
5)对于这个压力测试的说明:
宽带的最大传输是限制了你的请求量的。如果要完美测试就应该让你的宽带不成为瓶颈。
很多时候测试宽带都会成为瓶颈。你的网卡是M的。所以我们应该在本地测试。
公司里面的测试,有专门的测试服务器!这些服务器上面会安装很多的测试软件。根据你的需求选择测试软件,进行压力测试。测试的服务器,让网络上都不会成为瓶颈。
如果你的优化都OK了,但是性能还是上不去,就应该去查查原因。IO是成为瓶颈了吗?
注意:测试的时候,千万不要只测试一次,应该多测试几次,把结果汇总。去掉有问题的。然后取个平均数来进行说明就可以了。
2、真静态化
(1)ob缓存函数实践
查看ob缓存的函数:
flush — 刷新输出缓冲 //唯一一个可以控制PHP程序缓冲的函数
ob_clean — 清空(擦掉)输出缓冲区
ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲
ob_flush — 冲刷出(送出)输出缓冲区中的内容
ob_get_clean — 得到当前缓冲区的内容并删除当前输出缓。
ob_get_contents — 返回输出缓冲区的内容
ob_get_flush — 刷出(送出)缓冲区内容,以字符串形式返回内容,并关闭输出缓冲区。
ob_get_length — 返回输出缓冲区内容的长度
ob_get_level — 返回输出缓冲机制的嵌套级别
ob_get_status — 得到所有输出缓冲区的状态
ob_gzhandler — 在ob_start中使用的用来压缩输出缓冲区中内容的回调函数。ob_start callback function to gzip output buffer
ob_implicit_flush — 打开/关闭绝对刷送
ob_list_handlers — 列出所有使用中的输出处理程序。
ob_start — 打开输出控制缓冲
ob开头的,都是控制ob缓冲的内容:
ob_clean :清空ob缓存的内容!
清空是离自己最近的ob缓存!
ob_flush :刷出ob缓存的内容!
刷头是离自己最近的ob缓存。
ob_end_clean :清空ob缓存,并关闭ob缓存
ob_end_flush :刷出ob缓存的内容,并关闭ob缓存
ob_get_contents :获得ob缓存的内容
1)确定现在是不是有默认一个ob缓冲
echo ob_get_level();
,如果打印一个1,则是开启缓冲。
2)查看php.ini里面的配置:
配置文件里有一个:output_buffering = 4096
。这个是设置ob缓冲的大小。On是打开,空间很多;Off是关闭
如果要关闭,则修改成output_buffering = Off
,重启Apache,再访问刚才页面,会打印0,这就表示没有开启缓冲。
配置默认的值是4096,注意不要修改这个值,因为这个值是最合适的。
3)代码示意:
echo ob_get_levwl();
ob_start();
echo ob_get_level();
ob_start();
echo ob_get_level();
//访问结果:123
4)代码示意
ob_start(); //开启了第二个ob缓冲
echo '123'; //输出到了第二个ob缓冲里面
ob_start(); //开启了第三个ob缓冲
echo '456'; //输出到了第三个ob缓冲里面
ob_start(); //开启了第四个ob缓冲
echo '789'; //输出到了第四个ob缓冲里面
//程序结束了,就要开始回收资源,结束掉程序
//首先关闭第四个ob缓冲,里面的内容就到了第三个ob缓冲里面
//首先关闭第三个ob缓冲,里面的内容就到了第二个ob缓冲里面
//首先关闭第二个ob缓冲,里面的内容就到了第一个ob缓冲里面
//访问结果:123456789
5)代码示意
ob_start(); //开启了第二个ob缓冲
echo '123'; //输出到了第二个ob缓冲里面
ob_clean(); //清空当前缓冲内容
ob_start(); //开启了第三个ob缓冲
echo '456'; //输出到了第三个ob缓冲里面
ob_end_flush(); //刷出当前缓冲的内容,并且关闭它
ob_start(); //开启了第四个ob缓冲
echo '789'; //输出到了第四个ob缓冲里面
//访问结果:456789
6)代码示意
ob_start(); //开启了第二个ob缓冲
ob_clean(); //清空当前缓冲内容
echo '123'; //输出到了第二个ob缓冲里面
ob_start(); //开启了第三个ob缓冲
echo '456'; //输出到了第三个ob缓冲里面
ob_end_flush(); //刷出当前缓冲的内容,并且关闭它
ob_start(); //开启了第四个ob缓冲
echo '789'; //输出到了第四个ob缓冲里面
ob_fulsh(); //刷出到下一个ob缓冲里面
echo '0';
//访问结果:1234567890
7)代码示意
ob_start(); //开启了第二个ob缓冲
ob_clean(); //清空当前缓冲内容
echo '123'; //输出到了第二个ob缓冲里面
//输入的是回调函数名。只要经过ob缓冲就要调用它。刷出:关闭
ob_start('echohr');
echo '456'; //输出到了第三个ob缓冲里面
ob_end_flush(); //刷出当前缓冲的内容,并且关闭它
ob_start(); //开启了第四个ob缓冲
echo '0';
function echohr($content)
{
return '<hr>' . $content;
}
//访问结果:
123
————————————
4560
8)代码示意
ob_start(); //开启了第二个ob缓冲
ob_clean(); //清空当前缓冲内容
echo '123'; //输出到了第二个ob缓冲里面
//输入的是回调函数名。只要经过ob缓冲就要调用它。刷出:关闭
ob_start('echohr');
echo '456'; //输出到了第三个ob缓冲里面
ob_flush(); //刷出当前缓冲的内容,并且关闭它
ob_start(); //开启了第四个ob缓冲
echo '0';
function echohr($content)
{
return '<hr>' . $content;
}
//访问结果:
123
————————————
456
————————————
0
9)写一个有意思的代码:
//关闭默认ob缓冲
ob_end_clean();
//输出字符串4096
for($i = 1; $i < 9; $i++)
{
echo $i;
echo '<br>';
echo str_pad('', 4096);
flush(); //输出程序缓冲的内容
sleep(1);
}
//访问结果
1
2
3
4
5
6
7
8
修改一下:
//输出字符串4096
for($i = 1; $i < 9; $i++)
{
echo $i;
echo '<br>';
echo str_pad('', 4096);
//关闭默认ob缓冲
ob_flush(); //输出ob缓冲的内容
flush(); //输出程序缓冲的内容
sleep(1);
}
//访问结果
1
2
3
4
5
6
7
8
效果是一样的
10)非常重要的问题:
ob_end_clean();
echo '123';
header('Content-type:text/html;charset=utf-8');
echo '456';
//访问结果
123
警告信息。。。
456
报错原因说明:header是修改的是http协议内容。所以设置的信息,是直接发送到程序缓冲里面的。header的所有的设置,直接就到达程序缓冲里面。header前面是不能有任何输出内容的。
当你关闭了ob缓冲的时候,php输出的内容,就直接到达了程序缓冲,你在设置header的时候,就发现前面有内容了。既然有内容,也就有了默认的header设置。所以要报错的。
所以默认要开启一个ob缓冲;以后大家一定要注意,header前面不能有任何输出。
(2)ob缓存实现静态化
准备一个动态页面:
echo '<table border="2">';
for($i = 1; $i <= 9; $i++)
{
echo '<tr>';
for($j = 1; $j <= $i; $j++)
{
echo '<td>';
echo $i . ' X ' . $j . ' = ' . $i * $j;
echo '</td>';
}
echo '</tr>';
}
echo '</table>';
//上面所有的输出内容,都在ob缓冲里面
//获取到ob缓冲里面的全部内容就可以了
$res = ob_get_contents();
//存储成html页面
file_put_contents('99.html', $res);
运行这个代码后,在浏览器生成99乘法表,同时web目录下生成一个.html
这个静态文件,打开这个静态文静,里面的内容和刚才php生成的内容一模一样。
(3)静态化文件的生命周期
我们的访问页面,可以自动的设置生命周期,每一次过期了,都自动就生成一个新的静态化的页面!
什么样的页面才适合生成静态化的页面?
页面的数据很少变化才适合生成静态化的内容,现在很多网站都没有完全的静态化,都是局部静态化。要根据你的网页的情况来进行分析。
过期时间:假如是10秒。获取文件的修改时间:filemtime();
判断文件在不在:file_exists()
计算过期时间:
文件时间 + 过期时间 < 现在时间 : 过期
文件时间 + 过期时间 > 现在时间 : 不过期
代码实践一下:
//定义文件名
$filename = '99.html';
$time = 10;
//不过期就加载页面
if(file_exists($filename) && filemtime($filename) + $time > time())
{
include $filename;
}else
{
echo '<table border="2">';
for($i = 1; $i <= 9; $i++)
{
echo '<tr>';
for($j = 1; $j <= $i; $j++)
{
echo '<td>';
echo $i . ' X ' . $j . ' = ' . $i * $j;
echo '</td>';
}
echo '</tr>';
}
echo '</table>';
//上面所有的输出内容,都在ob缓冲里面
//获取到ob缓冲里面的全部内容就可以了
$res = ob_get_contents();
//存储成html页面
file_put_contents($filename, $res);
//为了测试方便,加入下面输出语句,
//已经过期的文件,会生成新的文件并显示下面的字符,再刷新时,'good'消失,表示还没有过期
echo 'good';
}
3、伪静态
(1)rewrite的介绍
使用了apache的rewrite规则来实现的效果。是通过apache接收到url之后,去判断这个url。通过判断的结果,重新定向到新的地址,或者新的文件。
这个功能web服务器都是存在的。但是每个web服务器都有一些区别。所以我们理解这些概念,用其它不同的web服务器的时候,就可以做相应的配置了。
比如:http://www.moumou/index.html
通过apache的路由规则,实现访问的页面是index.php的。
(2)rewrite的配置
1)打开扩展文件,位于Apache\conf\httpd.conf
。
开启模块:LoadModule rewrite_module modules/mod_rewrite.so
2)虚拟主机的配置文件httpd-vhosts.conf
里面添加:分布式支持
将AllowOverride All
添加到<Directory></Directory>
里面。
3)准备好分布式文件:
新建文件名:.htaccess
注意:没有办法右键->新建文件生成。 只能使用编辑器,生成这样一个文件!
分布式文件,一定是放在虚拟主机填写的web站点目录下面的。
4)实现:
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
#下面就写规则即可
</IfModule>
5)准备测试文件
.htaccess
,一开始生成的99乘法表99.thml
,新文件search.php
search.php
内容如下:
echo 'HelloWord!';
var_dump($_GET);
(3).htaccess文件:RewriteRule
1)规则:
如果url是index.php的时候,自动访问到search.php页面
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
#下面就写规则即可
#RewriteRule index.php search.php
</IfModule>
配置完成后,访问:域名/index.php时,会直接显示search.php里的内容。
2)文件名是XXX.html时,访问search.php
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# 使用正则的时候
#RewriteRule (.*).html search.php?id=$1
</IfModule>
3)重定向:302临时重定向
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# R 表示临时重定向
#RewriteRule index.php /search.php [R]
</IfModule>
4)永久重定向:301
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# R=301永久重定向
#RewriteRule index.php /search.php [R=301]
</IfModule>
说明:永久重定向是把定向地址写在了浏览的缓存里面;清了缓存就没有效果了。
重定向在写规则的时候,一定要加/
5)请求参数:
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# qsa把请求的参数也送过来
#RewriteRule (.*).php search.php?id=$1 [QSA]
</IfModule>
此时,在url地址输入参数时,输入的参数也会在页面从打印出来,因为search.php里面是var_dump($_GET);
(4).htaccess文件:RewriteCond
RewriteCond :使用这个的时候,可以获取apache里面的变量,把这些变量的值拿来进行匹配。
%{REQUEST_FILENAME} :获得文件路径
%{HTTP_REFERER} :获得url的来源地址
1)规则:判断url文件,或者是目录存不存在。
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# [NC] 不区分大小写;-f 判断文件;-d判断目录;! 取反
#RewriteCond %{REQUEST_FILENAME} !-f [NC]
#RewriteCond %{REQUEST_FILENAME} !-d [NC]
#RewriteRule (.*).html search.php?id=$1
</IfModule>
请求的url地址,不是目录也不是文件的时候,就走下面的路由。
比如说访问:124325.html
,很明显,刚才准备文件时没有准备叫这个名的文件,所以当url地址访问这个路由时,根据配置,会直接跳转到search.php
中。
如果访问的路由有该文件,则会访问这个文件。
发现:有文件的时候,是不是就是使用了真静态。
走了路由之后,就是伪静态;伪静态执行代码的时候,就可以根据条件,生成真静态。下一次访问的时候,就真的有页面了。
2)经常会使用的:去掉入口文件
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
#RewriteCond %{REQUEST_FILENAME} !-f [NC]
#RewriteCond %{REQUEST_FILENAME} !-d [NC]
#RewriteRule (.*) search.php?$1
</IfModule>
访问域名/home/co/act
时,还是会跳转到search.php
中,同时因为打印$_GET
,所以还是在浏览器显示出自己写的/home/co/act
路由。
3)来源的判断
写一个页面test.html
,在页面里显示一张图片<img src='xxx.jpg'>
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# 判断请求的来源,如果不是rewrite.com来的,就请求search.php
#RewriteCond %{HTTP_REFERER} !rewrite.com [NC]
#RewriteRule (jpg|png) search.php?$1
</IfModule>
RewriteCond %{HTTP_REFERER} !rewrite.com
判断请求的url是不是有来源,并且是rewrite.com这个的。如果不是就走下面的路由规则
RewriteRule (jpg|png) search.php?$1
判断这个url是不是请求的是jpg或者是Png 。如果是就走search.php。
在配置好分布式文件后,每一次url请求来了,都会走分布式文件,进行判断。
(5)经典功能-防盗链
防盗链:首先你有资源,然后被别人请求了。这个时候,你的服务器流量就被别人使用了。你要做的事情,就是防止别人使用你服务器的资源。这个就是防盗链。
实现一个非常节约的流量的访问,只要是别人引用你的信息,就直接返回403错误。
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# 返回一个403错误:[F]
RewriteCond %{HTTP_REFERER} !rewrite.com [NC]
RewriteRule (jpg|png|gif) -[F]
</IfModule>
做好这种配置后,别人家的网站访问我们网站时,在图片资源方面就会不再显示,但是自己家的访问是没有任何问题。
别人家的网站访问我们网站时,我们也可以给他们返回一个特定的图片
# 这个是分布式文件,修改了之后,不需要重启apache
# 检查rewrite扩展开启没有;没有开启就不报错
<IfModule mod_rewrite.c>
#开启rewrite
RewriteEngine On
# 返回一个403错误:[F]
RewriteCond %{HTTP_REFERER} !rewrite.com [NC]
RewriteRule (jpg|png|gif) xxx.jpg
</IfModule>
做好这样的配置,当别人家网站访问我们网站时就会显示出自己设置的特定图片了。