PHP MVC框架 视图之常用学习笔记

 更新时间:2016年11月25日 15:03  点击:1391
本文章来给大家介绍PHP MVC框架视图学习笔记,以方便以后需要参考。

今天来讲讲view,视图。。。没了解之前,你可能觉得模板引擎很神奇,了解了之后你会觉得,原来是如此简单。。。

对于模板引擎而言,它的原理一般是这样,把模板引擎的语言替换成可执行的语言,然后把变量输出。。。

因为PHP本身就是一个良好了模板引擎,所以用原生的模板引擎是灰常方便和容易做到的。。。


index.html

 代码如下 复制代码
 
<html>  
<head>  
    <title><?php echo $title ?></title>  
</head>  
<body>  
<h1><?php echo $content ?></h1>  
 
<?php if( ! empty($arr)) { ?>  
<ul>  
    <?php foreach($arr as $value) { ?>  
    <li><?php echo $value ?></li>  
    <?php } ?>  
</ul>  
<?php } ?>  
 
</body>  
</html> 

想上面这样一个html页面,采用的就是原生的php模板引擎,服务器在你include这个页面时,会处理html中的PHP代码。

你也许会问,要是我想定制模板语言可以吗?答案当然是可以的,像我上面说的,用模板引擎的语言,只需要多做一步,就是把模板引擎的语言替换成标准的PHP语言。。。

 index_2.html

 

 代码如下 复制代码
<html> 
<head> 
    <title><?php echo $title ?></title> 
</head> 
<body> 
<h1><?php echo $content ?></h1> 
 
<ifexist arr> 
<ul> 
    <for value = arr> 
    <li><echo value></li> 
    <endfor> 
</ul> 
<endexist> 
 
</body> 
</html> 

看看这个页面,发现和index.html 有什么不同吗,没错,就是在循环那里,我们用的不是标准的php语言,而是,按照自己的喜好,定义了几个模板语言,一个是<ifexist xxx>这个是判断xxx变量是否存在,而且不为空,后面那个<for xx1=xx2>是循环迭代xx2变量,中间的<echo xx> 是输出xx变量

怎么替换成标准语言呢?这个可以使用正则替换,因为字符串替换无法满足我们需求了。

 代码如下 复制代码
 
$pattern = array(  
    ‘/<ifexists+(w+)>/i’,  
    ‘/<fors+(w+)s=s(w+)>/’,  
    ‘/<echos+(w+)>/’  
);  
 
$replacement = array(  
    ‘<?php if( ! empty($\1)){ ?>’,  
    ‘<?php foreach($\2 as $\1){ ?>’,  
    ‘<?php echo $\1 ?>’  
);  
 
$content = preg_replace($pattern, $replacement, $content);  
 
$search = array(‘<endexist>’, ‘<endfor>’);  
 
 
$content = str_replace($search, ‘<?php } ?>’, $content); 

 

上面的正则就可以帮我们把刚刚定义的标签,转换成标准p hp语言。。。

转换之后是这样,请看图。

 

转换之后可以输出了吗?答案是不行的,因为你获取到html文件的内容的时候,php就已经解释了,那时候你还没替换成标准的php语言,所以,你现在输出的话,其中的php代码就没有执行。。。不过我们可以利用 php eval 这个函数,来强制要求执行其中的代码。

 代码如下 复制代码

$content = eval(‘ ?>’.$content);

注意哦,要 ?>.$content 要不,php会把其中的html当成是php代码的执行,这样就会出错了。。。

刷新一下,ok,已经可以执行了~~~

本文章来给各位介绍PHP MVC框架之加载器学习笔记,有需要了解的朋友可进入参考。

上节说了MVC的路由原理,这节我们来说说MVC框架的loader,也称为加载器。

虽然不同的框架,加载器的用法不同,但是其原理都是相通的。。。都是通过单例模式加载文件,而且把已加载的文件cache起来,避免重复加载。。。因为在开发业务的过程中,常常需要加载不同的模块,不同的类库等,MVC的loader可以帮助我们实现单例模式,更加符合开发需求。

下面我们开始动手,利用其原理,做一个简单的loader。


首先,我们设计的加载器,要满足可以全局使用,无论在controller里还是在model、library里都可以使用。

其次,加载器要有缓存能力,即相同的文件只加载一次,相同的类只实例化一次。

最后,要能加载多种文件,model、library、helper。

先解决第一步,怎么全局使用,最简单的办法就是定义一个全局的function,这样,在后面的不同类库,不同function里都可以调用这个全局function,进行加载文件。

第二步和第三步,要一起解决,定义一个单例模式的loader类,因为是单例模式,可以保证全局只有一份内容,这样的话,就可以利用数组把这些已加载的内容和对象cache起来,这样就可以避免了重复加载的问题。。。

 代码如下 复制代码
if ( ! function_exists(‘load’))  
{  
    function load($name, $type=’model’, $data=array())  
    {  
        static $loader = NULL;  
        if (is_null($loader))  
        {  
            include (ROOT.’/system/core/loader.php’);  
            $loader = Loader::get_instance();  
        }  
 
        return $loader->$type($name, $data);  
    }  

上面这个,就是我写的一个简单的全局函数 load,这个函数的作用就是为了可以全局调用,然后通过这个load函数,去调用loader类,由loader类负责加载文件,实例化,和缓存对象。。。下面我把loader的代码放出来给大家看看。

 代码如下 复制代码
<?php  
 
class Loader  
{  
    private $_loaded_models = array();  
    private $_loaded_librarys = array();  
    private static $OBJ;  
 
    # 单例模式,不允许new对象  
    private function __construct()  
    {  
 
    }  
 
 
    public static function get_instance()  
    {  
        if (is_null(self::$OBJ))  
        {  
            $class = __CLASS__;  
            self::$OBJ = new $class;  
        }  
          
        return self::$OBJ;  
    }  
 
    public function model($model, $data=array())  
    {  
        $model = strtolower($model);  
 
        # 如果已经加载,则返回对象,避免重复加载  
        if (isset($this->_loaded_models[$model]))  
        {  
            return $this->_loaded_models[$model];  
        }  
 
        # 否则加载文件  
        include ROOT.“/application/models/{$model}.php”;  
 
        $class = ucfirst($model);  
        # 实例化对象  
        if (emptyempty($data))  
        {  
            $instance = new $class;  
        }  
        else 
        {  
            $instance = new $class($data);  
        }  
        # 把对象cache起来  
        $this->_loaded_models[$model] = $instance;  
 
        return $instance;  
    }  
 
 
    public function library($library, $data=array())  
    {  
        $library = strtolower($library);  
 
        # 如果已经加载,则返回对象,避免重复加载  
        if (isset($this->_loaded_librarys[$library]))  
        {  
            return $this->_loaded_librarys[$library];  
        }  
 
        # 否则加载文件  
        include ROOT.“/application/librarys/{$library}.php”;  
 
        $class = ucfirst($library);  
        # 实例化对象  
        if (emptyempty($data))  
        {  
            $instance = new $class;  
        }  
        else 
        {  
            $instance = new $class($data);  
        }  
          
        # 把对象cache起来  
        $this->_loaded_librarys[$library] = $instance;  
 
        return $instance;  
    }  
 
 
}  
 
 
 
?> 

大家看到了没有,这个loader采用的是单例模式,虽然前面的function的设计已经可以保证不会重复实例化loader这个对象,但是为了真正可以保证全局只有一份loader对象,设计成单例模式是最保险的。。。

具体的测试例子请看代码。。。我把代码打包上传上来,有需要的就下载回去看看吧。。。下载后,解压,把lesson2文件夹放到你的www目录下,然后访问yourdomain/MVC/lesson2/index.php/index/test  试试看吧。。。

文章主要讲到关于php中慎用isset来判断数组是否存在key一些举例说明。

接上代码,  不知道是php5.4版本的问题, 还是本来就这样…

 代码如下 复制代码

$a['hello'] = ’123‘; 
$a['xx'] = NULL; 
 
var_dump(isset($a['hello'])); //bool(true) 
 
var_dump(isset($a['xx'])); //bool(false) 
 
# 应该使用这个来判断 
var_dump(array_key_exists(‘xx’, $a)); //bool(true)

PHP 5.3 加入了闭包语法,也就是匿名函数,允许开发者申明行内函数和在变量中保存。虽然这个语法和JavaScript的闭包相比有点怪异,但是对于PHP语言来说,这是一个良好的补充
 代码如下 复制代码
<?php
/**
* 下面提到的代码在PHP5.3以上版本运行通过.
*/
function callback($callback) {
$callback();
}
//输出: This is a anonymous function.<br />/n
//这里是直接定义一个匿名函数进行传递, 在以往的版本中, 这是不可用的.
//现在, 这种语法非常舒服, 和javascript语法基本一致, 之所以说基本呢, 需要继续向下看
//结论: 一个舒服的语法必然会受欢迎的.
callback(function() {
print "This is a anonymous function.<br />/n";
});
//输出: This is a closure use string value, msg is: Hello, everyone.<br />/n
//这里首先定义了一个闭包, 这次户口本上有名字了...
//use, 一个新鲜的家伙...
//众所周知, 闭包: 内部函数使用了外部函数中定义的变量.
//在PHP新开放的闭包语法中, 我们就是用use来使用闭包外部定义的变量的.
//这里我们使用了外部变量$msg, 定义完之后, 又对其值进行了改变, 闭包被执行后输出的是原始值
//结论: 以传值方式传递的基础类型参数, 闭包use的值在闭包创建是就确定了.
$msg = "Hello, everyone";
$callback = function () use ($msg) {
print "This is a closure use string value, msg is: $msg. <br />/n";
};
$msg = "Hello, everybody";
callback($callback);
//输出: This is a closure use string value lazy bind, msg is: Hello, everybody.<br />/n
//换一种引用方式, 我们使用引用的方式来use
//可以发现这次输出是闭包定义后的值...
//这个其实不难理解, 我们以引用方式use, 那闭包use的是$msg这个变量的地址
//当后面对$msg这个地址上的值进行了改变之后, 闭包内再输出这个地址的值时, 自然改变了.
$msg = "Hello, everyone";
$callback = function () use (&$msg) {
print "This is a closure use string value lazy bind, msg is: $msg. <br />/n";
};
$msg = "Hello, everybody";
callback($callback);
//输出: This is a closure use object, msg is: Hello, everyone.<br />/n
//闭包中输出的是之前被拷贝的值为Hello, everyone的对象, 后面是对$obj这个名字的一个重新赋值.
//可以这样考虑
//1. obj是对象Hello, everyone的名字
//2. 对象Hello, everyone被闭包use, 闭包产生了一个对Hello, everyone对象的引用
//3. obj被修改为Hello, everybody这个对象的名字
//4. 注意, 是名字obj代表的实体变了, 而不是Hello, everyone对象, 那自然闭包的输出还是前面的Hello, everyone
$obj = (object) "Hello, everyone";
$callback = function () use ($obj) {
print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";
};
$obj = (object) "Hello, everybody";
callback($callback);
//输出: This is a closure use object, msg is: Hello, everybody.<br />/n
//还是按照上面的步骤, 按部就班的来吧:
//1. obj名字指向Hello, everyone对象
//2. 闭包产生一个引用指向Hello, everyone对象
//3. 修改obj名字指向的对象(即Hello, everyone对象)的scalar值
//4. 执行闭包, 输出的自然是Hello, everybody, 因为其实只有一个真正的对象
$obj = (object) "Hello, everyone";
$callback = function () use ($obj) {
print "This is a closure use object, msg is: {$obj->scalar}. <br />/n";
};
$obj->scalar = "Hello, everybody";
callback($callback);
//输出: This is a closure use object lazy bind, msg is: Hello, everybody.<br />/n
//闭包引用的是什么呢? &$obj, 闭包产生的引用指向$obj这个名字所指向的地址.
//因此, 无论obj怎么变化, 都是逃不脱的....
//所以, 输出的就是改变后的值
$obj = (object) "Hello, everyone";
$callback = function () use (&$obj) {
print "This is a closure use object lazy bind, msg is: {$obj->scalar}. <br />/n";
};
$obj = (object) "Hello, everybody";
callback($callback);
/**
* 一个利用闭包的计数器产生器
* 这里其实借鉴的是python中介绍闭包时的例子...
* 我们可以这样考虑:
*         1. counter函数每次调用, 创建一个局部变量$counter, 初始化为1.
*         2. 然后创建一个闭包, 闭包产生了对局部变量$counter的引用.
*         3. 函数counter返回创建的闭包, 并销毁局部变量, 但此时有闭包对$counter的引用,
*             它并不会被回收, 因此, 我们可以这样理解, 被函数counter返回的闭包, 携带了一个游离态的
*             变量.
*         4. 由于每次调用counter都会创建独立的$counter和闭包, 因此返回的闭包相互之间是独立的.
*         5. 执行被返回的闭包, 对其携带的游离态变量自增并返回, 得到的就是一个计数器.
* 结论: 此函数可以用来生成相互独立的计数器.
*/
function counter() {
$counter = 1;
return function() use(&$counter) {return $counter ++;};
}
$counter1 = counter();
$counter2 = counter();
echo "counter1: " . $counter1() . "<br />/n";
echo "counter1: " . $counter1() . "<br />/n";
echo "counter1: " . $counter1() . "<br />/n";
echo "counter1: " . $counter1() . "<br />/n";
echo "counter2: " . $counter2() . "<br />/n";
echo "counter2: " . $counter2() . "<br />/n";
echo "counter2: " . $counter2() . "<br />/n";
echo "counter2: " . $counter2() . "<br />/n";
?>
为什么有些人php代码最后不加?>下面我给大家介绍介绍。

为什么有些人php代码最后不加“?>”呢?起初我也不知道,后来百度了才知道。网上看教程,别人都有“?>”结束标签,但是看别人的源码很多人都没有加,原来不加结束标签可以避免尾部的空白字符意外输出,对代码产生某些不必要的影响。

[!--infotagslink--]

相关文章

  • 基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍

    这篇文章主要介绍了基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍 的相关资料,需要的朋友可以参考下...2016-05-14
  • CI框架开发新浪微博登录接口源码完整版

    首先来看下流程:流程原理: 1.通过code获得access_token通过授权,并获取用户的信息(包括用户u_id)(这个u_id在后面的第三方登录表里面叫sina_id,那个表是需要自己建的) 2.查询第三方登录表,如果不存在用户sina_id,分2...2014-05-31
  • .net数据库操作框架SqlSugar的简单入门

    这篇文章主要介绍了.net数据库操作框架SqlSugar的简单入门,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下...2021-09-22
  • 记一次EFCore类型转换错误及解决方案

    这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
  • php上传图片学习笔记与心得

    我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
  • Smarty模板学习笔记之Smarty简介

    1、简介Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目...2014-05-31
  • c# 常用框架汇总

    这篇文章主要介绍了c# 常用框架汇总,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-04-24
  • AngularJS 视图详解及示例代码

    本文主要介绍AngularJS 视图,这里整理了相关知识,并附代码示例和实现效果图,有兴趣的小伙伴可以参考下...2016-08-27
  • 搭建php Laravel框架教程详解

    Laravel框架我们用到的不多了,但如果使用需要搭配了,下面我们来看一篇关于搭建php Laravel框架教程详解,具体的操作细节如下所示,希望对各位有帮助。 一、安装 Compos...2016-11-25
  • php Observer观察者模式之学习笔记

    当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了...2016-11-25
  • Java SSM框架如何添加写日志功能

    这篇文章主要介绍了Java SSM框架如何添加写日志功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-25
  • ASP.NET中iframe框架点击左边页面链接 右边显示链接页面内容

    这篇文章主要介绍了ASP.NET中iframe框架点击左边页面链接,右边显示链接页面内容的实现代码,感兴趣的小伙伴们可以参考一下...2021-09-22
  • PHP 日期函数 学习笔记介绍

    举一个简单的date例子 我将使用echo命令把内容输出到我们的客户端(浏览器)。我将使用下面的代码做为基础代码。 代码如下 复制代码 <!DOCTY...2016-11-25
  • node.js爬虫框架node-crawler初体验

    这篇文章主要介绍了node.js爬虫框架node-crawler的相关资料,帮助大家利用node.js进行爬虫,感兴趣的朋友可以了解下...2020-10-29
  • iOS实现圆角箭头视图

    这篇文章主要为大家详细介绍了iOS实现圆角箭头视图,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-04-16
  • 支持python的分布式计算框架Ray详解

    Ray是一种分布式执行框架,便于大规模应用程序和利用先进的机器学习库,今天给大家分享支持python的分布式计算框架Ray详解,感兴趣的朋友一起看看吧...2021-07-29
  • 第一次接触神奇的前端框架vue.js

    第一次接触神奇的vue.js,主要了解一下v-model、v-if、v-else、v-show、v-for等,感兴趣的小伙伴们可以一起学习一下...2016-12-02
  • BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)

    这篇文章主要介绍了BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)的相关资料,需要的朋友可以参考下...2016-12-02
  • 上手简单,功能强大的Python爬虫框架——feapder

    这篇文章主要介绍了上手简单,功能强大的Python爬虫框架——feapder的使用教程,帮助大家更好的利用python进行爬虫,感兴趣的朋友可以了解下...2021-04-26
  • 初识angular框架后的所思所想

    这篇文章主要介绍了初识angular框架后的所思所想,学习认识angular后的一些个人问题总结,需要的朋友可以参考下...2016-02-21