bigsmoker 51future 技术宅
同学们好,又跟大家见面了,继上次发布得 ” “,已有一个星期了,今天给同学们带了得是”php 一步步实现mvc架构——view篇”。如果对设计模式不了解得同学,请看这篇 ” “。掌握设计模式,有利于理解mvc中各种模式得实现。
好了,言归正传。首先先了解下,什么是view 层。还记得 在 路由篇 中得那张图吗?为了更直观一些,我还是将这张图引入
看见那个view层了吧。对得,就是视图层。这个层就是今天得主角。
一 先说说实现思路,来看个view层代码
index.php
======================================================================
{{$test}}
{{$myname}}
{{foreach($memners as $k=>$v)}}
{{$v}}
{{endforeach}}
这些个奇葩得类似 {{$test}}的变量,就是模板变量,可能有同学说 里面不光是模板变量,还有
{{foreach}}之流,没做。在这个模板里,它们统统都叫 模板变量。
再来看下controller层代码
Test.php
======================================================================
function mytestAction()
{
//echo "hello";
//var_dump(func_get_args());
// $this->loadModel('http\models\Test');
$this->assign("test","mytestAction");
$this->assign("myname","hhh");
$this->assign('memners',array('a'=>1,'b'=>'2','c'=>3));
$this->display('index');
}
以上代码代码通过display,去调用 templates.php中的display方法来引用模板。那么这个display是什么鬼?哈哈,其实这个display就做两件事。
1 将index.php中的模板变量解析成 原生php语法
解析前的模板
======================================================================
{{$test}}
{{$myname}}
{{foreach($memners as $k=>$v)}}
{{$v}}
{{endforeach}}
======================================================================
解析后的模板
======================================================================
1,
'b' => '2',
'c' => 3,
); ?>
$v) {?>
======================================================================
没错,你可以用任何你能想得到的方法去实现。这里的实现思路就是用正则匹配,替换模板变量
具体实现步骤:
1通过template.php 中的display方法读取 模板流
2将模板流中的循环{{foreach($memners as $k=>$v)}}替换成 $v) {?>,{{endforeach}}替换成,{{$test}}替换成
3将controller方法mytestAction中的要赋值给模板的值,通过assign($key,$value)的方法赋值给templates.php中的varArr数组。这个vArr形如:vArr[“test”]=”mytestAction”。
以下是具体操作
给模板赋值
$this->assign(“test”,”mytestAction”);
$this->assign(“myname”,”hhh”);
$this->assign(‘memners’,array(‘a’=>1,’b’=>’2’,’c’=>3));
4将varArr中的值注入 模板流
注意
模板流 指用file_get_content,获取的字符串
二 讲完思路,我们上代码,具体看下如何实现
先看下架构图
======================================================================
======================================================================
上图cache 层就是最终引入的php文件(最终的视图模板)
======================================================================
1,
'b' => '2',
'c' => 3,
); ?>
$v) {?>
======================================================================
再看下http\controller\Test.php
assign("test","mytestAction");//模板赋值
$this->assign("myname","hhh");
$this->assign('memners',array('a'=>1,'b'=>'2','c'=>3));
$this->display('index');//调用templates/Test/mytest/index.php
}
function mytest3Action()
{
$this->assign("test","mytest3Action");
$this->assign("myname","hello");
$this->assign('memners',array('a'=>1,'b'=>'2','c'=>3));
$this->display('index');//调用templates/Test/mytest3/index.php
}
}
======================================================================
再看下 controller类,调用了Vendor\lib\templates.php的assign和display方法
======================================================================
templatesObj = (new templates());
}
function display($name, ...$arguments)
{
$this->templatesObj->display($name, $arguments);
}
function assign($k,$v)
{
$this->templatesObj->assign($k,$v);
}
}
======================================================================
继续查看Vendor\lib\templates.php
======================================================================
controller=basename(str_replace("\\","/",$GLOBALS['controller']))??'index';
$this->method=str_replace("Action","",$GLOBALS['method'])??'index';
$this->suffix='.php';
}
function display($tpl,$compileDir='')
{
$this->tpl[$this->controller][$this->method] = TPLROOT.DIRECTORY_SEPARATOR.$this->controller.DIRECTORY_SEPARATOR.$this->method.DIRECTORY_SEPARATOR.$tpl.$this->suffix??"";
$pattern = "#{{(.*?)}}#i";
$content = file_get_contents($this->tpl[$this->controller][$this->method]);
$res = $this->replacePattern($pattern,$content);
$compileDir =COMPILEPATH.DIRECTORY_SEPARATOR.$this->controller.DIRECTORY_SEPARATOR.$this->method.DIRECTORY_SEPARATOR;
$this->compile($res,$compileDir,$tpl);
require $this->cacheFile;
}
function assign($k,$v)
{
$this->vArr[$k] = $v;
}
function compile($content,$complieDir,$tplname)
{
$this->cacheFile = $complieDir.$tplname.'.php';
if(is_dir($complieDir))
{
return file_put_contents($this->cacheFile,$content);
} else {
mkdir($complieDir,0777,true);
return file_put_contents($this->cacheFile,$content);
}
}
function setPatternFlag($left,$right)
{}
function parseVar($pattern,$content)
{
preg_match_all($pattern,$content,$matches);
$replacements = [];
foreach ($matches[1] as $k=>$v) {
$matches[0][$k] = '/'.addcslashes($matches[0][$k],'(,$,)').'/';
if(preg_match("#(foreach.*\((.*?)\))#i",$v))
{
$replacements [$k] = "";
} else if(preg_match("#(endforeach)#i",$v)){
$replacements [$k] = "";
}else {
$replacements [$k] = "";
}
}
$content = preg_replace($matches[0],$replacements,$content);
$phpVar = '';
foreach ($this->vArr as $k=>$v)
{
if(is_array($v))
{
$phpVar .= "";
} else {
$phpVar .= "";
}
}
return $phpVar.$content;
}
function replacePattern($pattern,$content)
{
return $this->parseVar($pattern,$content);
}
}
======================================================================
先来看下assign(),很简单,就是将值放入数组,以便将值注入 模板流
======================================================================
function assign($k,$v)
{
$this->vArr[$k] = $v;
}
======================================================================
display 函数的作用是将模板变成 模板流( file_get_contents($this->tpl[$this->controller][$this->method]) ),然后调用 replacePattern方法将模板流中的模板变量替换成 的形式。用file_put_content方法及将其写入cache/Test/mytest/index.php中。再 通过 require cache/Test/mytest/index.php 加载视图
======================================================================
function display($tpl,$compileDir='')
{
$this->tpl[$this->controller][$this->method] = TPLROOT.DIRECTORY_SEPARATOR.$this->controller.DIRECTORY_SEPARATOR.$this->method.DIRECTORY_SEPARATOR.$tpl.$this->suffix??"";
$pattern = "#{{(.*?)}}#i";
$content = file_get_contents($this->tpl[$this->controller][$this->method]);
$res = $this->replacePattern($pattern,$content);
$compileDir =COMPILEPATH.DIRECTORY_SEPARATOR.$this->controller.DIRECTORY_SEPARATOR.$this->method.DIRECTORY_SEPARATOR;
$this->compile($res,$compileDir,$tpl);
require $this->cacheFile;//引入模板流生成的php文件
}
======================================================================
再来看下最重要的replacePattern方法,这个方法的作用就是替换模板变量{{}}为
然后用compile 方法读取replacePattern出来的流,写入cache对应的目录,如cache/Test/mytest/index.php
效果图
function mytest3Action()
{
$this->assign("test","mytest3Action");
$this->assign("myname","hello");
$this->assign('memners',array('a'=>1,'b'=>'2','c'=>3));
$this->display('index');
}
function mytestAction()
{
//echo "hello";
//var_dump(func_get_args());
// $this->loadModel('http\models\Test');
$this->assign("test","mytestAction");
$this->assign("myname","hhh");
$this->assign('memners',array('a'=>1,'b'=>'2','c'=>3));
$this->display('index');
}
视图层的简单实现今天就讲到这,有兴趣的同学不妨自己试试怎么实现。
接下来要讲得是php 一步步实现mvc架构——model篇。同学们 敬请期待。下期再见
相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~