静态化,真静态技术。
采用php的ob缓存技术实现,结合手写模版引擎代码。
一个小实例,新闻管理系统。
项目说明:
为了便于SEO,要将新闻的页面做成静态化的页面。网址是静态的html,内容也是静态的。(如果只是网址是静态的,内容是动态的,就是伪静态,一般网站使用的都是伪静态技术股。)
网址静态化(点击之后跳转到静态化的网页):
项目结构介绍:
- admin:后台管理文件夹。
- index.html:后台管理首页。
- newsadd.php:后台添加新闻页面。
- newsupdate.php:后台修改新闻页面。
- newsupdatelist.php:后台修改新闻列表。
- cache:缓存文件夹:用开存储静态网页。
- 原理解释:在添加新闻的时候,就利用ob缓存技术,生成了静态页面,存放的地址就是cache。之后点击的每条新闻,其实是从这里提取,不在通过数据库。
- includes:页面解析及其生成静态文件,核心代码。参考手写模版引擎
- Parser.class.php:解析类
- Templates.class.php:模板文件
- templates:模板文件夹,存放用于显示信息的模板文件。
- conn.php:数据库配置文件
- newslist.php:首页,新闻显示页面。
- template.inc.php:模板配置文件。
- test.php:测试文件,用于测试使用。
conn.php:
代码;
<?php //连接数据库参数 define('DB_HOST', 'localhost'); define('DB_NAME', 'db_news'); define('DB_USER', 'root'); define('DB_PWD', '123456'); define('DB_CHARSET', 'UTF8'); //连接数据库 mysql_connect(DB_HOST,DB_USER,DB_PWD) or die('数据库连接失败!'); mysql_select_db(DB_NAME) or die('选择数据库失败!'); mysql_query("SET NAMES '" . DB_CHARSET. "'") or die('设置字符集编码出错!');
templates.inc.php:
<?php //创建网站根目录常量 define('ROOT_PATH', dirname(__FILE__) . DIRECTORY_SEPARATOR); //模板文件目录 define('TPL_DIR', ROOT_PATH . 'templates' . DIRECTORY_SEPARATOR); //缓存目录 define('CACHE', ROOT_PATH . 'cache' . DIRECTORY_SEPARATOR); //是否开启缓存 define('IS_CACHE', true); IS_CACHE ? ob_start() : NULL; //引入模板类 require ROOT_PATH . 'includes' . DIRECTORY_SEPARATOR . 'Template.class.php'; ?>
newslist.php:首页:
代码:
<?php /** * 显示新闻列表 */ header('Content-Type:text/html; charset="UTF-8"'); require dirname(__FILE__) . '/conn.php'; $query = 'SELECT id, title, content, time FROM `news`'; $resHandle = mysql_query($query); ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>新闻列表显示</title> <style type="text/css"> li{height:50px;} </style> </head> <body> <h2><a href="admin/index.html">进入后台</a></h2> <ul> <?php while (!!$result = mysql_fetch_array($resHandle,MYSQL_ASSOC)) { ?> <li> <a href="cache/News_id<?php echo $result['id']; ?>.html"><?php echo $result['title']; ?></a> -- <span><?php echo $result['content']; ?></span> -- <span><?php echo $result['time']; ?></span> </li> <?php } ?> </ul> </body> </html>
admin-->index.html:
代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>后台管理页面</title> </head> <body> <ul> <li><a href="newsadd.php">添加新闻</a></li> <li><a href="newsupdatelist.php">修改新闻</a></li> </ul> </body> </html>
admin-->newsadd.php页面:
代码:
<?php; /** * 添加新闻 */ require $_SERVER['DOCUMENT_ROOT'] . '/static/conn.php'; require $_SERVER['DOCUMENT_ROOT'] . '/static/templates.inc.php'; //插入数据库数据 if ( isset($_POST['submit']) ) { mysql_query("INSERT into news (title,content) VALUES ('".$_POST['title']."','".$_POST['content']."')"); if ( mysql_affected_rows() == '1' ) { //静态化页面 //实例化模版类 $template = new Templates(); //注入变量 $template->assign('title',$_POST['title']); $template->assign('content',$_POST['content']); //调用display方法 $template->display('details.tpl',mysql_insert_id()); header('location:http://localhost/static/newslist.php'); } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <META HTTP-EQUIV="pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate"> <META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"> <META HTTP-EQUIV="expires" CONTENT="0"> <title>添加新闻</title> </head> <body> <form action="newsadd.php" method="post"> <table> <tr> <td>新闻标题</td> <td><input type="text" name="title"/></td> </tr> <tr> <td>新闻内容</td> <td><textarea rows="3" cols="14" name="content"></textarea></td> </tr> <tr><td><input type="submit" name="submit" value="提交"/></td></tr> </table> </form> </body> </html>
admin-->newsupdate.php:后台新闻修改页面:
代码:
<?php /** * 显示新闻列表 */ header('Content-Type:text/html; charset="UTF-8"'); require $_SERVER['DOCUMENT_ROOT'] . '/static/conn.php'; require $_SERVER['DOCUMENT_ROOT'] . '/static/templates.inc.php'; $result = NULL; if (isset($_GET['id']) && !empty($_GET['id']) ) { $id = $_GET['id']; $res = mysql_query("select id, title, content from news where id= ".$_GET['id']); $result = mysql_fetch_array($res,MYSQL_ASSOC); } if ( isset($_POST['submit']) ) { mysql_query("UPDATE news SET title = '".$_POST['title']."' ,content = '".$_POST['content']."' WHERE id = '".$_POST['id']."'"); if (mysql_affected_rows() == '1') { //实例化模版类 $template = new Templates(); //注入变量 $template->assign('title',$_POST['title']); $template->assign('content',$_POST['content']); //调用display方法 $template->display('details.tpl',$_POST['id']); header('location:http://localhost/static/admin/newsupdatelist.php'); } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <META HTTP-EQUIV="pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate"> <META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"> <META HTTP-EQUIV="expires" CONTENT="0"> <title>添加新闻</title> </head> <body> <form action="newsupdate.php" method="post"> <table> <tr> <td>新闻标题</td> <td><input type="hidden" name="id" value="<?php echo $result['id'] ?>" /><input type="text" name="title" value="<?php echo $result['title']; ?>"/></td> </tr> <tr> <td>新闻内容</td> <td><textarea rows="3" cols="14" name="content"><?php echo $result['content']; ?></textarea></td> </tr> <tr><td><input type="submit" name="submit" value="修改"/></td></tr> </table> </form> </body> </html>
admin-->newsupdatelist.php:后台修改新闻列表页:
代码:
<?php /** * 显示新闻列表 */ header('Content-Type:text/html; charset="UTF-8"'); require $_SERVER['DOCUMENT_ROOT'] . '/static/conn.php'; require $_SERVER['DOCUMENT_ROOT'] . '/static/templates.inc.php'; $result = NULL; if (isset($_GET['id']) && !empty($_GET['id']) ) { $id = $_GET['id']; $res = mysql_query("select id, title, content from news where id= ".$_GET['id']); $result = mysql_fetch_array($res,MYSQL_ASSOC); } if ( isset($_POST['submit']) ) { mysql_query("UPDATE news SET title = '".$_POST['title']."' ,content = '".$_POST['content']."' WHERE id = '".$_POST['id']."'"); if (mysql_affected_rows() == '1') { //实例化模版类 $template = new Templates(); //注入变量 $template->assign('title',$_POST['title']); $template->assign('content',$_POST['content']); //调用display方法 $template->display('details.tpl',$_POST['id']); header('location:http://localhost/static/admin/newsupdatelist.php'); } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <META HTTP-EQUIV="pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate"> <META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"> <META HTTP-EQUIV="expires" CONTENT="0"> <title>添加新闻</title> </head> <body> <form action="newsupdate.php" method="post"> <table> <tr> <td>新闻标题</td> <td><input type="hidden" name="id" value="<?php echo $result['id'] ?>" /><input type="text" name="title" value="<?php echo $result['title']; ?>"/></td> </tr> <tr> <td>新闻内容</td> <td><textarea rows="3" cols="14" name="content"><?php echo $result['content']; ?></textarea></td> </tr> <tr><td><input type="submit" name="submit" value="修改"/></td></tr> </table> </form> </body> </html>
cache-->News_id57.html
代码:
<?php /** * 显示新闻列表 */ header('Content-Type:text/html; charset="UTF-8"'); require $_SERVER['DOCUMENT_ROOT'] . '/static/conn.php'; require $_SERVER['DOCUMENT_ROOT'] . '/static/templates.inc.php'; $result = NULL; if (isset($_GET['id']) && !empty($_GET['id']) ) { $id = $_GET['id']; $res = mysql_query("select id, title, content from news where id= ".$_GET['id']); $result = mysql_fetch_array($res,MYSQL_ASSOC); } if ( isset($_POST['submit']) ) { mysql_query("UPDATE news SET title = '".$_POST['title']."' ,content = '".$_POST['content']."' WHERE id = '".$_POST['id']."'"); if (mysql_affected_rows() == '1') { //实例化模版类 $template = new Templates(); //注入变量 $template->assign('title',$_POST['title']); $template->assign('content',$_POST['content']); //调用display方法 $template->display('details.tpl',$_POST['id']); header('location:http://localhost/static/admin/newsupdatelist.php'); } } ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <META HTTP-EQUIV="pragma" CONTENT="no-cache"> <META HTTP-EQUIV="Cache-Control" CONTENT="no-cache, must-revalidate"> <META HTTP-EQUIV="expires" CONTENT="Wed, 26 Feb 1997 08:21:57 GMT"> <META HTTP-EQUIV="expires" CONTENT="0"> <title>添加新闻</title> </head> <body> <form action="newsupdate.php" method="post"> <table> <tr> <td>新闻标题</td> <td><input type="hidden" name="id" value="<?php echo $result['id'] ?>" /><input type="text" name="title" value="<?php echo $result['title']; ?>"/></td> </tr> <tr> <td>新闻内容</td> <td><textarea rows="3" cols="14" name="content"><?php echo $result['content']; ?></textarea></td> </tr> <tr><td><input type="submit" name="submit" value="修改"/></td></tr> </table> </form> </body> </html>
includes-->parser.class.php:
代码:
<?php /** * 模板解析类 */ class Parser { //存储模板内容 private $_tplcontent; /** * 构造函数,获取模板内容 */ public function __construct($_tplPath) { if ( !$this->_tplcontent = file_get_contents($_tplPath) ) { exit('ERROR:获取模板文件出错!'); } } /** * 解析普通变量 */ private function parVar() { //替换变量的正则表达式 $_patten = '/{$([w]+)}/'; //如果匹配成功,则替换变量 if ( preg_match($_patten, $this->_tplcontent) ) { //[ 1 ],正则表达式,得到替换的内容。 $this->_tplcontent = preg_replace($_patten, '<?php echo $this->_vars["1"];?>', $this->_tplcontent); } else { exit($this->_tplcontent); } } /** * 解析if语句 */ private function parIf() { $_varStartIf = '/{ifs+($([w]+))}/'; $_varMidlleElse = '/{else}/'; $_varEndIf = '/{/if}/'; if ( preg_match($_varStartIf, $this->_tplcontent) ) { if (preg_match($_varEndIf, $this->_tplcontent) ) { //替换头if $this->_tplcontent = preg_replace($_varStartIf, '<?php if ($this->_vars["1"]) { ?>', $this->_tplcontent); //替换尾if $this->_tplcontent = preg_replace($_varEndIf, '<?php } ?>', $this->_tplcontent); //替换 else if ( preg_match($_varMidlleElse, $this->_tplcontent) ) { $this->_tplcontent = preg_replace($_varMidlleElse, '<?php } else { ?>', $this->_tplcontent); } } else { exit('ERROR:if语句没有关闭!'); } } } /** * 解析Foreach语句 */ private function parForeach() { $_pattenStartForeach = '/{foreachs+$([w]+)(([w]+),([w]+))}/'; $_pattenMiddleForeach = '/{@([w]+)}/'; $_pattenEndForeach = '/{/foreach}/'; if ( preg_match($_pattenStartForeach, $this->_tplcontent) ) { if ( preg_match($_pattenEndForeach, $this->_tplcontent) ) { //替换开头和结尾 $this->_tplcontent = preg_replace($_pattenStartForeach, '<?php foreach ($this->_vars["1"] as $2=>$3) { ?>', $this->_tplcontent); $this->_tplcontent = preg_replace($_pattenEndForeach, '<?php } ?>', $this->_tplcontent); //替换中间内容 if ( preg_match($_pattenMiddleForeach, $this->_tplcontent) ) { $this->_tplcontent = preg_replace($_pattenMiddleForeach, '<?php echo $1; ?>', $this->_tplcontent); } } else { exit('ERROR:foreach标签没有关闭!'); } } } /** * 解析include语句 */ private function parInclude() { $_pattenInclude = '/{#includes+file="([w.-]+)"}/'; if ( preg_match($_pattenInclude, $this->_tplcontent,$_file) ) { //判断被包含文件是否存在 if ( !file_exists($_file[1]) || empty($_file[1]) ) { exit('ERROR:包含文件出错!'); } //替换为PHP代码 $this->_tplcontent = preg_replace($_pattenInclude, '<?php include "1"; ?>', $this->_tplcontent); } } /** * 解析系统变量 */ private function parConfig() { $_pattenConfig = '/<!--{([w]+)}-->/'; if (preg_match($_pattenConfig, $this->_tplcontent) ) { $this->_tplcontent = preg_replace($_pattenConfig, '<?php echo $this->_config["1"]; ?>', $this->_tplcontent); } } /** * 解析注释 */ private function parCommon() { $_patten = '/{#}(.*){#}/'; if ( preg_match($_patten, $this->_tplcontent) ) { $this->_tplcontent = preg_replace($_patten, '<?php /* 1 */ ?>', $this->_tplcontent); } } /** * 调用各个解析方法解析文件,并最终生成编译文件 */ public function compile($_compileName) { //解析普通变量 $this->parVar(); //解析if语句 $this->parIf(); //解析include $this->parInclude(); //解析系统变量 $this->parConfig(); //解析注释 $this->parCommon(); //解析foreach $this->parForeach(); //经过解析变量,最后生成编译文件 if ( !file_put_contents($_compileName, $this->_tplcontent) ) { exit('ERROR:编译文件出错!'); } } } ?>
inlcudes-->Templates.class.php:
代码:
<?php /** * 模板类 */ class Templates { //存储注入的变量 private $_vars = array(); /** * 构造函数 */ public function __construct() { //验证各个目录是否存在 if ( !is_dir(TPL_DIR) || !is_dir(CACHE) ) { exit('ERROR:目录不存在,请添加!'); } } /** * 注入变量 */ public function assign($_varName, $_varValue) { //判断变量名称是否为空 if ( !isset($_varName) || empty($_varName) ) { exit('ERROR:变量名不能为空!'); } else { //将变量注入到数组中去 $this->_vars[$_varName] = $_varValue; } } /** * 显示模板文件 */ public function display($filename,$id) { //获取模板路径 $_tplPath = TPL_DIR . $filename; //判断模板文件是否存在 if ( !file_exists($_tplPath) ) { exit('ERROR:模板文件不存在!'); } //编译后文件的文件名 $_compileName = CACHE . 'News_id' . $id . '.php'; //缓存文件的文件名 $_cacheFileName = CACHE . 'News_id' . $id . '.html'; //引入解析类,将模板文件中的伪代码,解析为php代码,并生成编译文件。 require ROOT_PATH . 'includes' . DIRECTORY_SEPARATOR . 'Parser.class.php'; //声明类的时候,传入模板文件路径 $parser = new Parser($_tplPath); //调用解析方法的时候,传入编译文件名称 $parser->compile($_compileName); //载入生成的编译文件。载入后输出内容输出到浏览器,ob缓存进行读取。 include $_compileName; //是否开启了缓存 if ( IS_CACHE ) { //接受缓冲文件,并生成缓存文件 file_put_contents($_cacheFileName, ob_get_contents()); //清除缓冲区,并关闭缓存,意思就是清除了编译文件加载的内容。 ob_end_clean(); //删除编译文件 if ( file_exists($_compileName) ) { if ( !unlink($_compileName) ) { exit('编译文件未能及时删除,可能会造成服务器空间浪费,但不影响正常使用。'); } } } } } ?>
templates-->details.tpl:
代码:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>新闻显示</title> <style type="text/css"> .border, .border tr td{ border:1px solid #888; } </style> </head> <body> <table class="border"> <tr> <td>新闻标题</td> <td>新闻内容</td> </tr> <tr> <td>{$title}</td> <td>{$content}</td> </tr> </table> </body> </html>
----------------项目源码:网盘-->smarty文件夹下,文件名称:【静态化-真静态】