静态化,真静态技术。
采用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 = '/\{if\s+\(\$([\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 = '/\{foreach\s+\$([\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 = '/\{#include\s+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文件夹下,文件名称:【静态化-真静态】