HttpKernel组件:控制器解析器
编辑该页面HttpKernel组件:控制器解析器
你可能会认为我们的框架已经非常稳固的,也许你是对的。但让我们看看我们可以改善它。
现在,我们所有的例子使用程序代码,但请记住,控制器可以是任何有效的PHP回调。让我们转换控制器一个合适的类:
1 2 3 4 5 6 7 8 9 10 11
类LeapYearController{公共函数指数(美元请求){如果(is_leap_year (美元请求- >属性- >get (“年”))){返回新响应(“是的,这是一个闰年!”);}返回新响应(“不,这不是一个闰年。);}}
更新相应的路由定义:
1 2 3 4
美元路线- >add (“leap_year”,新路由\路线(“/ is_leap_year /{一}”,(“年”= >零,“_controller”= > [新LeapYearController (),“指数”)));
此举很简单和很有道理一旦你创造更多的页面,但是您可能已经注意到non-desirable副作用……的LeapYearController
类是总是实例化,即使您访问的地址或文件不匹配leap_year
路线。这是不好的一个主要原因是:属性,所有控制器对所有航线现在必须为每个请求实例化。最好是如果控制器是延迟加载,因此只有相关的控制器匹配路由被实例化。
为了解决这个问题,多一些,让我们安装和使用HttpKernel组件:
1
美元作曲家需要symfony / htob娱乐下载tp-kernel
HttpKernel组件有许多有趣的特性,但我们现在需要的是控制器解析器和参数解析器。一个控制器解析器知道如何确定执行控制器和参数解析器决定传递给它的参数,基于一个请求对象。所有控制器解析器实现以下接口:
1 2 3 4 5 6 7
名称空间ob娱乐下载\组件\HttpKernel\控制器;/ /……接口ControllerResolverInterface{公共函数getController(请求美元请求);}
的getController ()
方法依赖于相同的约定一个我们前面定义:_controller
请求属性必须包含与请求相关的控制器。除了内置的PHP回调,getController ()
还支持字符串组成的一个类名后跟两个冒号和方法名称作为一个有效的回调,像“class::方法”:
1 2 3 4
美元路线- >add (“leap_year”,新路由\路线(“/ is_leap_year /{一}”,(“年”= >零,“_controller”= >“LeapYearController:指数”)));
这段代码的工作,修改框架代码来使用控制器从HttpKernel解析器:
1 2 3 4 5 6 7 8 9
使用ob娱乐下载\组件\HttpKernel;美元controllerResolver=新HttpKernel \控制器\ ControllerResolver ();美元argumentResolver=新HttpKernel \控制器\ ArgumentResolver ();美元控制器=美元controllerResolver- >getController (美元请求);美元参数=美元argumentResolver- >getArguments (美元请求,美元控制器);美元响应=中的call_user_func_array (美元控制器,美元参数);
请注意
还有一个额外的好处,控制器正常解析器处理你的错误管理:当你忘了定义_controller
例如属性的一个途径。
现在,让我们看看控制器参数是猜测。getArguments ()
控制器签名自查,以确定哪些参数通过使用原生PHP反射。该方法定义在以下界面:
1 2 3 4 5 6 7
名称空间ob娱乐下载\组件\HttpKernel\控制器;/ /……接口ArgumentResolverInterface{公共函数getArguments(请求美元请求,美元控制器);}
的index ()
方法需要请求对象作为参数。getArguments ()
知道什么时候注入正确如果type-hinted正确:
1 2 3 4
公共函数指数(请求美元请求)/ /赢得了”t工作公共函数指数(美元请求)
更有趣的是,getArguments ()
也可以注入任何请求属性;如果论点有着同样的名字对应的属性:
1
公共函数指数(美元一年)
你也可以同时注入请求和一些属性(作为匹配是在参数名称或类型提示,参数顺序并不重要):
1 2 3
公共函数指数(请求美元请求,美元一年)公共函数指数(美元一年,请求美元请求)
最后,您还可以定义默认值的参数匹配请求的一个可选属性:
1
公共函数指数(美元一年=2012年)
让我们注入美元一年
我们的控制器请求属性:
1 2 3 4 5 6 7 8 9 10 11
类LeapYearController{公共函数指数(美元一年){如果(is_leap_year (美元一年)){返回新响应(“是的,这是一个闰年!”);}返回新响应(“不,这不是一个闰年。);}}
验证控制器的解析器也照顾可调用及其参数。对于一个问题,它与一个不错的消息抛出一个异常解释问题(控制器类不存在,没有定义的方法,论证没有匹配的属性,…)。
请注意
默认的控制器解析器的极大的灵活性和参数解析器,您可能想知道为什么有人会想要创建另一个(为什么有一个接口如果不是吗?)。两个例子:在Symfony中,ob娱乐下载getController ()
增强的支持控制器作为服务;和getArguments ()
提供了一个扩展点来改变或提高参数的解决。
让我们总结与新版本的框架:
1 2 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 34 35 36 37 38 39 40 41
/ / example.com/web/front.phprequire_once__DIR__。“/ . . /供应商/ autoload.php”;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;使用ob娱乐下载\组件\HttpKernel;使用ob娱乐下载\组件\路由;函数render_template(请求美元请求){提取(美元请求- >属性- >所有(),EXTR_SKIP);ob_start ();包括sprintf (__DIR__。“/ . . / src /页面/ % s.php ',美元_route);返回新响应(ob_get_clean ());}美元请求=请求::createFromGlobals ();美元路线=包括__DIR__。“/ . . / src / app.php”;美元上下文=新路由\ RequestContext ();美元上下文- >fromRequest (美元请求);美元匹配器=新路由\匹配器\ UrlMatcher (美元路线,美元上下文);美元controllerResolver=新HttpKernel \控制器\ ControllerResolver ();美元argumentResolver=新HttpKernel \控制器\ ArgumentResolver ();试一试{美元请求- >属性- >add (美元匹配器- >匹配(美元请求- >getPathInfo ()));美元控制器=美元controllerResolver- >getController (美元请求);美元参数=美元argumentResolver- >getArguments (美元请求,美元控制器);美元响应=中的call_user_func_array (美元控制器,美元参数);}抓(路由\异常\ ResourceNotFoundException美元异常){美元响应=新响应(“没有找到”,404年);}抓(异常美元异常){美元响应=新响应(“出错”,500年);}美元响应- >send ();
再次想想:我们的框架比以往任何时候都更健壮、更灵活,它仍小于50行代码。