前期回顾:
【笔记】 + php构造自己MVC的框架(一)
很抱歉现在才发续集,也不知道这半年忙了什么;
废话少说,这次我们共同学习构造TPL模板引擎:
先上图,直观了当:
1.开天辟地(创建所需要的文件)
1)index.php入口文件;
2)controller\ 存放控制器的文件夹;
3)model\ 存放模型的文件夹;
4)view\ 存放视图模板的文件夹;;
5)common\ 存放公共文件的文件夹;
6)cache\ 存放由TPL模板引擎生成静态文件的文件夹;
7)configs\ 存放配置文件的文件夹;
8)include\ 解析类文件存放的文件夹;
9)templates_c\ 编译文件存放的文件夹;
2.制定万物法则(解析规则,文件规则)
1)include\Parse.php
[PHP] 纯文本查看 复制代码 class Parse{ //把试图界面中的规则解析成PHP的写法,最后再写到模板中
private $contents;
function __construct($_tpl)
{
$this->contents=file_get_contents($_tpl);
}
public function complile(){
$this->parseVars();
$this->parseIf();
$this->parseForeach();
$this->parseInclude();
$this->parseXml();
return $this->contents;
}
private function parseVars(){
//解析变量发给complile
$patten1='/\{\$(\w+)\}/';
$str1="<?php echo \$this->arr['$1']?>";
if(preg_match($patten1,$this->contents)){
$this->contents=preg_replace($patten1,$str1,$this->contents);
// echo htmlspecialchars($some) ;
// echo $some;
}
}
private function parseIf(){
//解析条件判断发给complile
$patten1='/\{if\s\$(\w+)\}/';//{if $a}
$patten2='/\{\/if\}/';//{/if}
$patten3='/\{else\}/';//{else}
$patten4='/\{else\sif\s\$(\w+)\}/';//{else}
$str1="<?php if ('$1'){ ?>";
$str2="<?php } ?>";
$str3="<?php }else{ ?>";
$str4="<?php }else if('$2'){ ?>";
if(preg_match($patten1,$this->contents) && preg_match($patten2,$this->contents)){
$this->contents=preg_replace($patten1,$str1,$this->contents);
$this->contents=preg_replace($patten2,$str2,$this->contents);
if(preg_match($patten3,$this->contents)){ //查找是否存在else
echo "____";
$this->contents=preg_replace($patten3,$str3,$this->contents);
}
if(preg_match($patten4,$this->contents)){
$this->contents=preg_replace($patten4,$str4,$this->contents);
}
}
}
private function parseForeach(){
//解析变量发给complile
$patten1='/\{foreach\s\$array\(key\,values\)\}/';//{foreach $array(key,values)}
$patten2='/\{\/foreach\}/';
$patten3='/\{@key\}/';// <li class="{@key}">{@values}</li>
$patten4='/\{@values\}/';
$str1="<?php foreach(\$this->arr as \$key=>\$values){ ?>";//
$str2="<?php } ?>";
$str3="<?php echo \$key?>";
$str4="<?php echo \$values?>";
if(preg_match($patten1,$this->contents) && preg_match($patten2,$this->contents)){
// echo "_____foreach";
$this->contents=preg_replace($patten1,$str1,$this->contents);
$this->contents=preg_replace($patten2,$str2,$this->contents);
$this->contents=preg_replace($patten3,$str3,$this->contents);
$this->contents=preg_replace($patten4,$str4,$this->contents);
}
/* $arr=array(1=>1,2=>2,3=>3);
foreach($arr as $item=>$value){
echo "item=$item.______value=$value<br>";
}
exit;*/
}
private function parseInclude(){
$patten1='/\{include\s\"/'; //{include "nav.tpl
$patten2='/\"\}/'; //"}
$str1="<?php include '";
$str2="'?>";
if(preg_match($patten1,$this->contents)){
echo "_____Include";
$this->contents=preg_replace($patten1,$str1,$this->contents);
$this->contents=preg_replace($patten2,$str2,$this->contents);
}
}
public function parseXml(){
//解析变量发给complile
$patten1='/\{\$(\w+)\}/';
/* $str1="<?php echo \$this->arr['$1']?>";*/
if(preg_match($patten1,$this->contents)){
echo "___";
// $this->contents=preg_replace($patten1,$str1,$this->contents);
}
}
}
2)在我们创造试图文件的时候,要对应 控制器/方法.html
3)创造控制器的时候要用xxxxController命名类名,模板要用xxxModel命名类名。
3.创造生机(构造MVC)
1)view\index\index.html
[HTML] 纯文本查看 复制代码 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{$title}</title>
</head>
<body>
{$content}
</body>
</html>
还有报错页(404)面也要有:view\index\error.html
[HTML] 纯文本查看 复制代码 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>探索</title>
<style>
.main{
/*position: absolute;*/
/*top:50%;*/
/*left:50%;*/
/*transform: translate(-50%,-50%);*/
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
margin:auto;
height: 200px;
text-align: center;
}
</style>
</head>
<body>
<div class="main">
<h1>NOT FOUND 404</h1>
<a >自动跳转请点击</a>
<p>还有 <span id="daojishi">5</span>后自动跳转</p>
</div>
</body>
<script>
window.onload=function(){
var daojishi=document.getElementById("daojishi").innerHTML;
var _url="http://localhost/php/MVCpro/index.php?c=index&a=index";
var shaoID=setInterval(function(){
daojishi--;
if(daojishi!=-1){
console.log(daojishi);
document.getElementById("daojishi").innerHTML=daojishi;
}else{
clearInterval(shaoID)
location.href=_url;
}
},1000);
}
</script>
</html>
2)model\Index.php
[PHP] 纯文本查看 复制代码 class IndexModel{
public function index(){
return array("title"=>"测试页面","content"=>"这是一个测试页面呀!");
}
}
3)controller\Index.php
[PHP] 纯文本查看 复制代码 class IndexController{
private $indexModel;
function __construct()
{
$this->indexModel=M("index");
}
public function index(){
//从MODEL层获取数据
$_arr=$this->indexModel->index();
$title=$_arr['title'];
$content=$_arr['content'];
//echo $title,$content;
$_tpl=new Templates();
$_tpl->assign("title",$title);
$_tpl->assign("content",$content);
$_tpl->fetch('index/index');
}
public function error(){
include "view/index/error.html";
}
}
其他页面方法请自行添加;
4.发现文明
1)include\Templates.php
[PHP] 纯文本查看 复制代码 class Templates{
// 注入数据的方法:
private $arr=array();//用来接收用户发来的数据:
public function assign($_key,$_values){
$this->arr[$_key]=$_values;
}
// 显示哪个试图层的
public function fetch($view){
if(file_exists("view/$view.html")){
$_path="view/$view.html";
}else{
$_path="view/$view.xml";
}
$_tplc="templates_c/".md5($view).".php";
$cacheName="cache/".md5($view).".html";
if(file_exists($_tplc) && (filemtime($_tplc)<filemtime($cacheName))){
echo "___这是读取的模板文件";
require $cacheName;
}else{
/////转义文本
$pareseOne=new Parse($_path);
$content= $pareseOne->complile();
/////将文本生成动态文件
file_put_contents($_tplc,$content);
include $_tplc;
//////抓取页面,并生成缓存文件
$youNeed=ob_get_contents(); //抓取页面信息,生成静态文件
file_put_contents($cacheName,$youNeed);
}
}
}
5.桃花源的发现:
首先我们写一个common\function.php来处理路由(单一入口文件)
[PHP] 纯文本查看 复制代码 define('ERROE_URL','Location:http://localhost/php/MVCpro/index.php?c=index&a=error');//定义错误页面
function C(){
$c=isset($_GET["c"])?$_GET["c"]:"index"; //此乃调用哪个控制器
$a=isset($_GET["a"])?$_GET["a"]:"index"; //此乃调用哪种方法
$c=ucfirst($c);
if(!file_exists("controller/$c.php")){ //判断控制器是否存在
header(ERROE_URL);
}
require "controller/$c.php"; //引入控制器
$className=$c."Controller";
$user=new $className(); //实例化控制器
if(!method_exists($className,$a)){ //判断方法是否存在
header(ERROE_URL);
}
$user->$a(); //调用方法
}
function M($_type){
$_type=ucfirst($_type);
require "model/$_type.php";
$className=$_type."Model";
$some=new $className();
return $some;}
接着我们写入口文件index.php
[PHP] 纯文本查看 复制代码 header("Content-type:text/html;charset=utf8");
require "include/Templates.php";
require "include/Parse.php";
require "common/function.php";
C();
这样,一个超级超级简单的tpl模板引擎就成功了,去打开http://localhost/php/MVCpro/index.php试试吧。
差不多就是这样, 最后在把一些常量,数据库啊等等的信息加到configs\config.inc.php里面(此处截至,不做展示)。
|