首页 » PHP教程 » php简略的mvc技巧_php 一步步实现mvc架构view篇

php简略的mvc技巧_php 一步步实现mvc架构view篇

duote123 2024-10-30 0

扫一扫用手机浏览

文章目录 [+]

同学们好,又跟大家见面了,继上次发布得 "php 一步步实现mvc架构——路由篇",已有一个星期了,本日给同学们带了得是"php 一步步实现mvc架构——view篇"。
如果对设计模式不理解得同学,请看这篇 "php根本-设计模式"。
节制设计模式,有利于理解mvc中各种模式得实现。

好了,言归正传。
首先先理解下,什么是view 层。
还记得 在 路由篇 中得那张图吗?为了更直不雅观一些,我还是将这张图引入

php简略的mvc技巧_php 一步步实现mvc架构view篇

瞥见那个view层了吧。
对得,便是视图层。
这个层便是本日得主角。

php简略的mvc技巧_php 一步步实现mvc架构view篇
(图片来自网络侵删)

一 先说说实现思路,来看个view层代码

index.php

======================================================================

<html><head>{{$test}}</head><body><div>{{$myname}}</div>{{foreach($memners as $k=>$v)}}<div>{{$v}}</div>{{endforeach}}</body></html>

这些个奇葩得类似 {{$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语法

解析前的模板

======================================================================

<html><head>{{$test}}</head><body><div>{{$myname}}</div>{{foreach($memners as $k=>$v)}}<div>{{$v}}</div>{{endforeach}}</body></html>

======================================================================

解析后的模板

======================================================================

<?php $test ='mytestAction'; ?><?php $myname ='hhh'; ?><?php $memners =array ( 'a' => 1, 'b' => '2', 'c' => 3,); ?><html><head><?php echo $test?></head><body><div><?php echo $myname?></div><?php foreach($memners as $k=>$v) {?> <div><?php echo $v?></div><?php }?></body></html>

======================================================================

没错,你可以用任何你能想得到的方法去实现。
这里的实现思路便是用正则匹配,更换模板变量

详细实现步骤:

1通过template.php 中的display方法读取模板流

2将模板流中的循环{{foreach($memners as $k=>$v)}}更换成 <?php foreach($memners as $k=>$v) {?>,{{endforeach}}更换成<?php }?>,{{$test}}更换成<?php echo $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文件(终极的视图模板)

======================================================================

<?php $test ='mytestAction'; ?><?php $myname ='hhh'; ?><?php $memners =array ( 'a' => 1, 'b' => '2', 'c' => 3,); ?><html><head><?php echo $test?></head><body><div><?php echo $myname?></div><?php foreach($memners as $k=>$v) {?> <div><?php echo $v?></div><?php }?></body></html>

======================================================================

再看下http\controller\Test.php

<?php/ Created by PhpStorm. User: mario Date: 2021/1/26 Time: 0:39 /namespace http\controllers;class Test extends controller{ function mytestAction() { $this->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方法

======================================================================

<?phpnamespace http\controllers;use Vendor\lib\templates;class controller { protected $model = null; private $templatesObj = null; function __construct() { $this->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

======================================================================

<?phpnamespace Vendor\lib;use IFS\Template\Template;class templates implements Template{ private $tpl=[]; private $vArr = []; private $controller; private $method; private $suffix; private $cacheFile; function __construct() { $this->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] = "<?php ".$v." {?>"; } else if(preg_match("#(endforeach)#i",$v)){ $replacements [$k] = "<?php }?>"; }else { $replacements [$k] = "<?php echo ".$v."?>"; } } $content = preg_replace($matches[0],$replacements,$content); $phpVar = ''; foreach ($this->vArr as $k=>$v) { if(is_array($v)) { $phpVar .= "<?php \$$k =".var_export($v,true)."; ?>"; } else { $phpVar .= "<?php \$$k ='".$v."'; ?>"; } } 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方法将模板流中的模板变量更换成 <?php ?>的形式。
用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方法,这个方法的浸染便是更换模板变量{{}}为<?php ?>

然后用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篇。
同学们 敬请期待。
下期再见

标签:

相关文章

世界城市代码图解码城市发展与未来趋势

城市已成为经济发展和社会进步的重要载体。为了更好地了解和研究城市,人们开始关注城市代码图。本文将围绕世界城市代码图,探讨城市发展与...

PHP教程 2025-03-16 阅读1 评论0

3010节点代码网络世界的智慧枢纽

在信息化时代,网络已成为人们生活中不可或缺的一部分。而网络世界的运转离不开各种节点代码的支撑。今天,就让我们来揭秘3010节点代码...

PHP教程 2025-03-16 阅读1 评论0

Java代码虚拟化保护技术与应用前景

软件应用的需求日益增长,软件开发过程中对代码的保护成为了一个重要议题。Java作为一种广泛应用于企业级应用的编程语言,其代码虚拟化...

PHP教程 2025-03-02 阅读1 评论0