为什么要是用静态页面?
先来看看php在服务器的执行过程:当用户请求服务器php文件的时候,服务器将对php文件进行语法分析,其次是解析,最后才运行。当php文件有内容输出时,该内容会先经过服务器的php的缓冲区(buffer),然后再通过TCP传递到客户端。(buffer其实就是缓冲区,一个内存地址空间,主要用于存储数据区域)。
可见,如果用户直接访问静态页面的时候,服务器的响应时间一般会比访问动态文件的时间短。如果我们能把用户将要访问的动态文件先转化为静态文件即可加快用户访问页面的速度(获取网页的速度)。
同时对于一个访问量可能达百万、千万级别的网站来说,每次用户点击动态链接的时候都会对服务器发送数据查询的要求,这无疑是服务器一个大大的负担!就算是访问量级没那么大,每次都请求数据库,也是一个不太好的选择,所以把动态数据转换成静态的html页面,从一定程度上就可以减少对数据库的压力,用PHP生成静态页面也成了一个刚需。。
当然我们要注意静态化的应用场景,页面的静态化主要应用于那些页面内容不经常改动的页面。
关于静态化,PHP的静态化分为:纯静态和伪静态。其中纯静态又分为:局部纯静态和全部纯静态。
怎么生成静态页面呢?
第一种:利用模板。
目前PHP的模板可以说是很多了,有功能强大的smarty,还有简单易用的smarttemplate等。它们每一种模板,都有一个获取输出内容的函数。我们生成静态页面的方法,就是利用了这个函数。用这个方法的优点是,代码比较清晰,可读性好。
这里我用smarty做例子,说明如何生成静态页:
<?php require_once('Smarty/Smarty.class.php'); $smarty = new Smarty(); //用于存放smarty模版文件,如果未指定该路径,Smarty会自动在当前目录中寻找模版文件。 $smarty->template_dir = 'templates/'; //用于存放smarty编译后的文件,如果不指定该目录,Smarty会自动在当前脚本所在目录下生成一个名为'templates_c'的目录用于存放生成的编译文件。 $smarty->compile_dir = 'templates_c/'; //用于存放smarty配置文件 $smarty->config_dir = 'smaconfigs/'; //用于存放smarty缓存文件,如果开启Smarty缓存功能,但没有指定该目录,Smarty会自动在当前脚本所在目录下生成一个名为'cache'的目录用于存放缓存文件。 $smarty->cache_dir = 'cache/'; $smarty->assign("name","Hello World!"); $content = $smarty->fetch("templates/index.tpl"); //这里的 fetch() 就是获取输出内容的函数,现在$content变量里面,就是要显示的内容了 $fp = fopen("test.html", "w"); fwrite($fp, $content); fclose($fp);
第二种方法:利用ob系列的函数。
ob_start 打开输出控制缓冲(要求php开启缓存,在php配置文件php.ini文件中可以设置 output_buffering = on) ob_get_contents 读取缓冲区内容 ob_clean 清空(擦掉)输出缓冲区 ob_get_clean 得到当前缓冲区的内容并删除当前输出缓冲区 ob_end_flush 关闭浏览器缓存 php生成文件的函数 file_put_contents('文件路径','文件内容')。(当然php中还有其他写文件的方法,如fwrite) fopen(”文件路径”,”打开模式”)打开文件 这个函数的打开模式有好几种 下面介绍几种主要的模式: “r” 只读方式打开,将文件指针指向文件头。 “r+” 读写方式打开,将文件指针指向文件头。 “w” 写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 “w+” 读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。 fwrite(”文件名称”,”写入内容”) 写入文件 fclose() 关闭文件
这里用到的函数主要是 ob_start(), ob_end_flush(), ob_get_content(),其中ob_start()是打开输出缓冲的意思,打开缓冲后,所有来自PHP程序的非文件头信息均不会发送,而是保存在内部缓冲区,直到你使用了ob_end_flush().而这里最重要的一个函数,就是ob_get_contents(),这个函数的作用是获取缓冲区的内容,相当于上面的那个fetch(),道理一样的。
<?php ob_start(); echo "Hello World!"; $content = ob_get_contents();//取得php页面输出的全部内容 $fp = fopen("staticPage.html", "w"); fwrite($fp, $content); fclose($fp);
1、使用PHP文件读写功能生成静态页面
<?php $data = '<!DOCTYPE html> <html lang=""> <head> <meta charset="utf-8"> <title>网页静态化</title> </head> <body> <h1>排名</h1> <ul> <li>No.1</li> <li>No.2</li> <li>No.3</li> <li>No.4</li> <li>No.5</li> </ul> </body> </html>'; $fp = fopen("index.html", "w"); if (!$fp) { echo "System Error"; exit(); } fwrite($fp, $data); fclose($fp); echo "生成 index.html 成功!";
其中"$data"数据是解析好的前端代码,若包含 PHP 原生代码是无法解析的,那如何把动态的 PHP 语言静态化?
2、PHP OB 缓存机制生成静态页面
<?php ob_start(); require_once('index.php'); // 引入模版文件 $data = ob_get_contents(); file_put_contents('index.html', $data); // 生成静态文件 index.html ob_end_clean(); // 输出信息并清除缓存 $fp = fopen("index.html", "w"); if (!$fp) { echo "System Error"; exit(); } fwrite($fp, $data); fclose($fp); echo "生成 index.html 成功!";
全部纯静态--根据静态文件失效的时间,判断是否重新生成静态文件 index.shtml
<?php //1、连接数据库,然后从数据库里面获取数据 //2、把获取到的数据填充到模板文件里面 //3、需要把动态的页面转化为静态页面,生成纯静态化文件 if(is_file('index.shtml') && (time() - filemtime('index.shtml')) < 300) { //设置缓存失效时间 require_once('index.shtml'); } else { require_once('db.php'); $connect = Db::getInstance()->connect(); $sql = "SELECT * FROM news WHERE `category_id` = 1 AND `status` = 1 ORDER BY id DESC LIMIT 5"; $result = mysql_query($sql, $connect); $news = array(); while($row = mysql_fetch_array($result)) { $news[] = $row; } //print_r($news); ob_start(); //开启缓存区 //引入模板文件 require_once('templates/singwa.php'); //动态文件 singwa.php界面同样进过缓冲区 file_put_contents('index.shtml', ob_get_contents()); /*if(file_put_contents('index.shtml', ob_get_clean())) { echo 'success'; } else { echo 'error'; }*/ }
singwa.php(使用bootstrap框架做界面)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>新闻中心</title> <link rel="stylesheet" href="public/css/bootstrap.min.css" type="text/css"> </head> <body> <div> <h3>新闻列表</h3> <ul> <?php foreach ($news as $key => $value) { ?> <li><a href="#"><?php echo $value['title'];?></a></li> <?php } ?> </ul> </div> </body> </html>
当我们第一次访问 index.php时,服务器将为我们生成一个静态文件index.shtml。
当我们不超过300秒,再次访问index.php时,服务器将访问静态文件index.shtml给我们访问。而当静态文件过期后,我们再次访问index.php,服务器将为我们更新index.shtml静态文件。
触发系统生成纯静态化页面方式
这里讲到的只是一种触发静态(页面添加缓存时间)文件更新的方法,当然还有:手动触发更新(设置后台管理,管理员想立即更新静态文件,就点击运行生成静态文件即可)、Linux服务器下的crontab定时扫描程序(在Linux服务器下,设置命令:
* /1 * * * * php 路径+文件名 ==> 代表 每一分钟系统将执行一次指定文件
require_once('db.php'); $connect = Db::getInstance()->connect(); $sql = "SELECT * FROM news WHERE `category_id` = 1 AND `status` = 1 ORDER BY id DESC LIMIT 5"; $result = mysql_query($sql, $connect); $news = array(); while($row = mysql_fetch_array($result)) { $news[] = $row; } //print_r($news); ob_start(); //开启缓存区 //引入模板文件 require_once('templates/singwa.php'); //动态文件 singwa.php界面同样进过缓冲区 file_put_contents('index.shtml', ob_get_contents());
伪静态实现
伪静态就是通过某些技术(如rewrite)把动态网页的URL地址伪装成静态网页URL地址,但实质上用户访问的还是动态网页,只不过URL地址看起来是符合静态网页地址特征,因此,用户及某些搜索引擎会误认为其是静态网页。
下面我们对"http://www.test.vip/web/article?id=1"地址分别在Nginx和Apache上做伪静态处理。
1). Nginx 伪静态
(1)在nginx.conf 合适位置加入 rewrite 语句,代码如下:
rewrite ^/web/article/(\d).html$ /web/article.php?id=$1 last;
rewrite语法
指令语法:rewrite regex replacement [flag] regex :表示正则匹配规则。 replacement :表示跳转后的内容。 flag :表示 rewrite 支持的 flag 标记。 应用位置:server、location、if regex 常用正则表达式: 字符 描述 \ 将后面接着的字符标记为一个特殊字符或者一个原义字符或一个向后引用 ^ 匹配输入字符串的起始位置 $ 匹配输入字符串的结束位置 * 匹配前面的字符零次或多次 + 匹配前面的字符一次或多次 ? 匹配前面的字符零次或一次 . 匹配除“\n”之外的所有单个字符 (pattern) 匹配括号内的pattern flag 标记符号 说明 last 本条规则匹配完成后继续向下匹配新的location URL 规则 break 本条规则匹配完成后终止,不在匹配任何规则 redirect 返回302临时重定向 parmanent 返回301永久重定向
2).Apache 伪静态
(1)在Apache配置文件httpd.conf 中启用Rewrite,去除前面的"#",使apache支持 mod_rewrite 模块,代码如下:
LoadModule rewrite_module modules/mod_rewrite.so
(2)在服务器找到配置文件vhosts.conf,启用 .htaccess,打开虚拟机配置文件vhosts.conf,找到其中的"AllowOverride"项,将它的值修改为All。
(3)完成修改后保存,并重新启动Apache服务器,使修改生效。
(4)接下来在项目的根目录下创建一个.htaccess 文件,实现对PHP文件后缀的隐藏操作。.htaccess文件的格式如下:
< IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine on RewriteRule index.html index.php RewriteRule ^/article/(\d+).html$ /web/article.php?id=$1 # 更多伪静态规则 < /IfModule>
PHP实现页面静态化:https://www.imooc.com/learn/330/
本文为崔凯原创文章,转载无需和我联系,但请注明来自冷暖自知一抹茶ckhttp://www.cksite.cn