手机版

自制PHP框架的路由和控制器

时间:2021-09-05 来源:互联网 编辑:宝哥软件园 浏览:

我们为什么要使用路由?理由1:一个更美丽的URI

1.1的改进。上呼吸道感染

当我们第一次开始学习PHP时,我们一定写过关于blog.php的文章?URI如id=1,通过GET获取参数。这个URI有两个缺点,一是容易被SQL注入攻击,二是可维护性和可读性差。你可以比较以下两个URIs哪个更易读。

www.mysite.com/blog.php?Id=1。上面的URI是PHP初学者最常用的一个。

Www.mysite.com/blog/1是目前最受欢迎的URI。比如很多阅读和电影网站都用这个URI,哪个比index.php好?A=1b=2c=3d=4.这要简单得多。

2.实现方法

在WEB项目的根目录中编写一个. htaccess文件

重写规则上的重写引擎([a-za-z0-9/]*)$ index.php/$1重写规则,让域名后面的字符串作为参数直接传入index.php,让index.php成为你整个WEB应用的中心,定义“请求和响应之间的映射”。

原因二:单一进入机制的可维护性

1.路由阵列

一个刚刚开始做这个项目的PHP初学者,把这个项目做得更大了。通常,这个PHP页面通过GET方法将值传递给另一个PHP页面,有时会传递多个值。时间长了,你的WEB项目和N个PHP页面就像一个复杂的蜘蛛网,让你很难维护。一旦有修改,就会涉及到很多PHP文件,工作量会很大。

MVC的单入口机制可以解决维护难的问题。路由是一组映射,允许您将URI对应到一个方法。

$route=[ ''='[emailprotected]',' blog'='[emailprotected]',' blog/{ id }/{ name } '='[email protected]',];2.获取参数

$ PATH=$ _ SERVER[' PATH _ INFO '];$path=ltrim($path,'/');echo $path。PHP _ EOL我们在浏览器中输入:www.mysite.com/blog/1后,路径变量为/blog/1。使用ltrim函数删除左斜杠,然后使用explode将字符串分解成数组。

$path_arr=explode('/',$ path);核心代码如下:

if(isset($ _ SERVER[' PATH _ INFO ']){ $ PATH=$ _ SERVER[' PATH _ INFO '];$path=ltrim($path,'/');$path_arr=explode('/',$ path);} if(isset($ path _ arr[0]){ $ key=$ path _ arr[0];unset($ path _ arr[0]);} else { $ key=} if(isset($ path _ arr[1]){ $ parameters=array _ values($ path _ arr);} if(isset($ route[$ key]){ $ arr=explode(' @ ',$ route[$ key]);$ controller=new $ arr[0];$ action=$ arr[1];if(isset($ parameters)){ $ controller-$ action($ parameters);} else { $ controller-$ action();} } else { require ' error . html . PHP ';}unset函数可以破坏数组中的键和值,但不会重建索引,因此path_arr[0]是要调用的控制器类和方法名,path_arr[1]或path_arr[1.n]作为传入方法的参数。

重定向和错误页面是WEB系统中最常见的。如果不使用路由机制,可能要没完没了地写重定向或错误页面的显示或跳转代码。有了路由,一句话就能完成。

原因三:减少资源消耗

MVC使用一个控制器来响应请求。每次有请求到来,控制器都应该在指定的PHP文件中初始化,而不是在不同的PHP文件中初始化,这样可以减少资源的消耗。

你一定要用控制器吗?方案一:无控制器

我们现在向路由阵列添加一个项目。值不是字符串,而是匿名函数(闭包)

$route=[ ''='Index ',' blog'='[emailprotected]',' blog/{ id }/{ name } '='[email protected]',' f '=function(){ echo ' hello ';}];Route[f]这里是一个匿名函数,不是控制器类的方法,所以我们需要修改上一节中的路由代码:

if(isset($ route[$ key]){ if($ route[$ key]instance of Closure){ $ route[$ key]);} else{ $arr=explode('@ ',$ route[$ key]);$ controller=new $ arr[0];$ action=$ arr[1];if(isset($ parameters)){ $ controller-$ action($ parameters);} else { $ controller-$ action();} } } else { require ' error . html . PHP ';}选项2:使用控制器

每次都需要一个html页面并不优雅,所以我们编写了一个渲染函数

函数render($path,array $ args){ extract($ args);require($ path);}在上一篇博客中,我们知道每个URI对应一个方法,但我们经常会遇到这样的问题:

?php类Controller { public function _ _ call($ method,$args){ echo '没有此函数'。$方法;}} class IndexController扩展了Controller { public function Index(){ echo _ _ CLASS _ _;for($ I=1;$ i=20$ I){ $ data[$ I]=' content ';} render('template.html.php ',[' data '=$ data]);}} class BlogController扩展了Controller { public function Show(){ echo _ _ CLASS _ _;for($ I=1;$ i=10$ I){ $ data[$ I]=' blog ';} render('template.html.php ',[' data '=$ data]);}} ?您是否使用控制器取决于您业务的复杂性。个人建议使用控制器,但简单的页面跳转或业务检查可以直接写在匿名函数中。

控制器里写了什么?

我们可能编写了这样的代码:

class IndexController扩展了Controller { public function Index($ content){ return ' html head/head dy '。$内容。/body/html ';}}这种嵌入接口代码的方式很难维护,也是很多开发者(包括我)最恶心的方式。因为这种编写方式没有将接口和业务逻辑分开,所以我们需要使用视图。

html头/头体?PHP foreach($ data as $ key=$ value){?div?php echo $key。':'.$ value?/div?php }?/body/htmle每次调用控制器的某个方法时,render函数都会以关联数组的形式传入参数,从而实现“业务逻辑”和“表示”的浅层分离,但这种分离并不是最好的,因为前端开发人员仍然需要面对甚至处理PHP代码,而后端开发人员也有与前端人员沟通的成本,因此更好的分离方法将在后面的章节中讨论。

版权声明:自制PHP框架的路由和控制器是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。