模板
编辑本页模板
精明的读者已经注意到,我们的框架硬编码了特定“代码”(模板)的运行方式。对于像我们到目前为止创建的这些简单页面,这不是问题,但是如果您想添加更多的逻辑,您将被迫将逻辑放入模板本身,这可能不是一个好主意,特别是如果您仍然牢记关注点分离原则的话。
让我们通过添加一个新层将模板代码从逻辑中分离出来:控制器:控制器的任务是根据客户端请求传递的信息生成响应。
修改框架的模板渲染部分如下所示:
1 2 3 4 5 6 7 8 9 10 11
/ / example.com/web/front.php/ /……试一试{$请求->属性->add ($匹配器->匹配($请求->getPathInfo ()));$响应= call_user_func (“render_template”,$请求);}抓(路由\异常\ ResourceNotFoundException$异常) {$响应=新响应(“没有找到”,404);}抓(异常$异常) {$响应=新响应(“发生错误”,500);}
由于渲染现在是由外部函数(render_template ()
这里),我们需要将从URL中提取的属性传递给它。我们可以把它们作为附加参数传递给render_template ()
的另一个特性请求
类属性:请求属性是一种附加关于请求的附加信息的方法,这些信息与HTTP请求数据不直接相关。
您现在可以创建render_template ()
函数,该通用控制器在没有特定逻辑时呈现模板。为了与之前的模板保持一致,在模板呈现之前提取请求属性:
1 2 3 4 5 6 7 8
函数render_template($请求){提取($请求->属性->所有(),EXTR_SKIP);ob_start ();包括sprintf (__DIR__.“/ . . / src /页面/ % s.php ',$_route);返回新响应(ob_get_clean ());}
作为render_template
作为PHPcall_user_func ()
函数,我们可以用任何有效的PHP替换它回调.这允许我们使用一个函数,一个匿名函数或一个类的方法作为控制器…你的选择。
作为约定,对于每个路由,关联的控制器都是通过_controller
路由属性:
12 3 4 5 6 7 8 9 10 11 12 13
$路线->add (“你好”,新路由\路线(“/ hello /{名称}”, (“名字”= >“世界”,“_controller”= >“render_template”)));试一试{$请求->属性->add ($匹配器->匹配($请求->getPathInfo ()));$响应= call_user_func ($请求->属性->get (“_controller”),$请求);}抓(路由\异常\ ResourceNotFoundException$异常) {$响应=新响应(“没有找到”,404);}抓(异常$异常) {$响应=新响应(“发生错误”,500);}
路由现在可以与任何控制器相关联,并且在一个控制器内,您仍然可以使用render_template ()
渲染一个模板:
1 2 3 4 5 6
$路线->add (“你好”,新路由\路线(“/ hello /{名称}”, (“名字”= >“世界”,“_controller”= >函数($请求){返回render_template ($请求);}));
这是相当灵活的,因为你可以更改响应对象之后,你甚至可以传递额外的参数给模板:
12 3 4 5 6 7 8 9 10 11 12 13 14
$路线->add (“你好”,新路由\路线(“/ hello /{名称}”, (“名字”= >“世界”,“_controller”= >函数($请求){// $foo将在模板中可用$请求->属性->集(“foo”,“酒吧”);$响应= render_template ($请求);//更改一些头文件$响应->头->集(“内容类型”,“文本/普通”);返回$响应;}));
以下是我们框架的更新和改进版本:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
/ / example.com/web/front.phprequire_once__DIR__.“/ . . /供应商/ autoload.php”;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;使用ob娱乐下载\组件\路由;函数render_template($请求){提取($请求->属性->所有(),EXTR_SKIP);ob_start ();包括sprintf (__DIR__.“/ . . / src /页面/ % s.php ',$_route);返回新响应(ob_get_clean ());}$请求=请求::createFromGlobals ();$路线=包括__DIR__.“/ . . / src / app.php”;$上下文=新路由\ RequestContext ();$上下文->fromRequest ($请求);$匹配器=新路由\匹配器\ UrlMatcher ($路线,$上下文);试一试{$请求->属性->add ($匹配器->匹配($请求->getPathInfo ()));$响应= call_user_func ($请求->属性->get (“_controller”),$请求);}抓(路由\异常\ ResourceNotFoundException$异常) {$响应=新响应(“没有找到”,404);}抓(异常$异常) {$响应=新响应(“发生错误”,500);}$响应->send ();
为了庆祝新框架的诞生,让我们创建一个全新的应用程序,它需要一些简单的逻辑。我们的应用程序有一个页面,说明给定的一年是否是闰年。当调用/ is_leap_year
,您将得到当前年份的答案,但您也可以指定像in这样的年份/ is_leap_year / 2009
.由于框架是通用的,因此不需要以任何方式修改,创建一个新的框架app.php
文件:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
/ / example.com/src/app.php使用ob娱乐下载\组件\HttpFoundation\响应;使用ob娱乐下载\组件\路由;函数is_leap_year($一年= null){如果(零= = =$一年) {$一年=日期(“Y”);}返回0= = =$一年%400| | (0= = =$一年%4& &0= = !$一年%One hundred.);}$路线=新路由\ RouteCollection ();$路线->add (“leap_year”,新路由\路线(“/ is_leap_year /{一}”, (“年”= >零,“_controller”= >函数($请求){如果(is_leap_year ($请求->属性->get (“年”))) {返回新响应(“是的,今年是闰年!”);}返回新响应(“不,今年不是闰年。”);}));返回$路线;
的is_leap_year ()
函数返回真正的
当给定的年份是闰年时,假
否则。如果年份是零
,测试当年。控制器做的很少:它从请求属性中获取年份,并将其传递给is_leap_year ()
函数,并根据返回值创建一个新的Response对象。
与往常一样,您可以决定在这里停止,并使用框架;这可能是你创建简单网站所需要的,比如那些花哨的单页网站网站希望还有其他的。