PHP MVC框架路由学习笔记
说到PHP开发web,自然离不开开发框架,开发框架为我们提供了灵活的开发方式,MVC层分离,业务解耦等。。。
第一篇先来简单点的,说说MVC框架的路由功能。。。
一般的单入口框架路由都是这样的结构:
domain/index.php/classname/functionname/var1/var2
这里的index.php 就被称为入口文件。。。对于服务器而言,你这里访问的就只有index.php 后面调用的controller 和里面的方法,甚至传值都是在框架内部基于PHP层面实现的。
Talk is cheap, show you the code !!
首先,先建立好下面的文件结构
我们来动手试试,怎么才能访问到controllers里面的文件。。。
在index.php里面输入以下内容
print_r($_SERVER);
然后访问 以下地址试试。
yourdomain/index.php/class/function/var1
这里作者我是用本地环境的,我访问的地址是localhost/MVC/index.php/class/function/var1
我贴出最重要的2个变量
[REQUEST_URI] => /MVC/index.php/class/function/var1
[SCRIPT_NAME] => /MVC/index.php
其实路由最基本的原理就在这里:
通过这2个变量来提取url地址里的class 和 function,参数等,然后把class include进来,通过PHP的回调函数 call_user_func_array 调用对应的function和传递相应的参数。
接下来上代码,读代码应该比我写的易懂。哈哈~~
index.php 的内容如下
代码如下 | 复制代码 |
|
在application/controllers 里面添加下面2个文件
index.php 用于作为默认控制器
代码如下 | 复制代码 |
hello.php |
测试一下看看,能不能访问了。根据上面的路由结构。我们来试试
这个访问正常,正确调用了hello这个class内部的name方法,然后把参数barbery传递过去了。。。
再试试不输入function name,看看能不能默认调用index。。
答案也是可以的。。。
最后一个,访问root地址看看
也正确的映射到了默认控制器上。。。
ok,一个简单的MVC路由功能就完成了。。。
以前有讲过关于php mvc的各种用法,本文章主要介绍PHP MVC框架之错误捕捉用法说明,各位同学可参考。前三篇文章已经把MVC的结构原理都简单的进行了说明和演示。。。当然,不是说一个框架就只有那点东西,一个良好的框架所要求的功能还是要很全面的,例如友好的错误输出,安全处理,防止跨域攻击等
好了,我们一步一步来。这节要说的是错误捕捉,其实这个不难,只要理解2个方法就可以做好错误捕捉的程序。
代码如下 | 复制代码 |
|
第一个方法,是注册一个shutdown的回调函数,当php脚本关闭时调用,当然这个关闭可以是正常的代码执行完毕,也可以是程序抛出致命错误关闭的脚本,那我怎么区分呢?别急,php还有一个方法叫error_get_last() 就像函数名说的那样,获取php最后一个错误信息,这样就可以判断是代码正常执行完毕还是遇到fatal error。。。
第二个方法,是注册一个error的回调函数,当脚本执行遇到错误时调用。
这2个方法最大的区别是,第一个是脚本关闭调用,也就是1次访问,只会调用一次(因为发生致命错误脚本就退出执行了),二第二个方法的触发调用是发生错误的时候,例如访问数组中不存在的index,使用未定义的变量,就是这些warning,notice错误的捕捉。。。如果你想更了解二者的区别,建议访问php官网查看文档说明。。。
这里我就不贴代码了,有兴趣的同学,可以去github那里下回来慢慢看。。。
代码如下 | 复制代码 |
<?php # 定义application路径 define('APPPATH', trim(__DIR__,'/')); # 获得请求地址 $root = $_SERVER['SCRIPT_NAME']; $request = $_SERVER['REQUEST_URI']; $URI = array(); # 获得index.php 后面的地址 $url = trim(str_replace($root, '', $request), '/');
if (empty($url)) { # 默认控制器和默认方法 $class = 'Index'; $func = 'welcome'; } else { $URI = explode('/', $url);
if (count($URI) < 2) { $class = ucfirst($URI[0]); $func = 'index'; } else { $class = ucfirst($URI[0]); $func = $URI[1]; } }
# 把class加载进来 include(APPPATH . '/' . 'application/controllers/' . $class . '.php');
$obj = new $class;
# 调用内部function array($obj,$func), # 传递参数 array_slice($URI, 2) );
|
我们来看看最终的效果。。。我们来试试访问不存在的controller里的方法试试
先看看没有错误捕捉的时候:
再来对比下做了错误捕捉的时候
本文章来给各位介绍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 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中慎用isset来判断数组是否存在key一些举例说明。接上代码, 不知道是php5.4版本的问题, 还是本来就这样…
代码如下 | 复制代码 |
$a['hello'] = ’123‘; |
相关文章
- 这篇文章主要介绍了vue 实现动态路由的方法,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-06
基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍
这篇文章主要介绍了基于BootStrap Metronic开发框架经验小结【八】框架功能总体界面介绍 的相关资料,需要的朋友可以参考下...2016-05-14- 这篇文章主要介绍了.net数据库操作框架SqlSugar的简单入门,帮助大家更好的理解和学习使用.net技术,感兴趣的朋友可以了解下...2021-09-22
- 首先来看下流程:流程原理: 1.通过code获得access_token通过授权,并获取用户的信息(包括用户u_id)(这个u_id在后面的第三方登录表里面叫sina_id,那个表是需要自己建的) 2.查询第三方登录表,如果不存在用户sina_id,分2...2014-05-31
- 这篇文章主要介绍了记一次EFCore类型转换错误及解决方案,帮助大家更好的理解和学习使用asp.net core,感兴趣的朋友可以了解下...2021-09-22
解决vue动态路由异步加载import组件,加载不到module的问题
这篇文章主要介绍了解决vue动态路由异步加载import组件,加载不到module的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-27- 我们在php中上传文件就必须使用#_FILE变量了,这个自动全局变量 $_FILES 从 PHP 4.1.0 版本开始被支持。在这之前,从 4.0.0 版本开始,PHP 支持 $HTTP_POST_FILES 数组。这...2016-11-25
- 1、简介Smarty是一个使用PHP写出来的模板PHP模板引擎,是目前业界最著名的PHP模板引擎之一。它分离了逻辑代码和外在的内容,提供了一种易于管理和使用的方法,用来将原本与HTML代码混杂在一起PHP代码逻辑分离。简单的讲,目...2014-05-31
- 这篇文章主要介绍了解决vue-router路由拦截造成死循环问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-05
- 这篇文章主要介绍了c# 常用框架汇总,帮助大家更好的理解和学习使用c#,感兴趣的朋友可以了解下...2021-04-24
- 这篇文章主要给大家介绍了关于vue.js Router中嵌套路由的相关资料,所谓嵌套路由就是路由里面嵌套他的子路由,文章通过示例代码介绍的非常详细,需要的朋友可以参考下...2021-06-27
- 这篇文章主要介绍了vue-router路由参数刷新消失的问题...2017-06-24
- 这篇文章主要介绍了vue-router为激活的路由设置样式操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-07-18
- 这篇文章主要介绍了Vue鼠标滚轮滚动切换路由效果的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-08-04
- 当我们在星际中开地图和几家电脑作战的时候,电脑的几个玩家相当于结盟,一旦我们出兵进攻某一家电脑,其余的电脑会出兵救援。 那么如何让各家电脑知道自己的盟友被攻击了...2016-11-25
- Laravel框架我们用到的不多了,但如果使用需要搭配了,下面我们来看一篇关于搭建php Laravel框架教程详解,具体的操作细节如下所示,希望对各位有帮助。 一、安装 Compos...2016-11-25
- 这篇文章主要介绍了springboot中nacos动态路由的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
- 这篇文章主要介绍了Java SSM框架如何添加写日志功能,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-09-25
- 这篇文章主要介绍了react自动化构建路由的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-23
- 这篇文章主要介绍了如何制作自己的原生JavaScript路由,对路由感兴趣的同学,可以参考下...2021-05-04