前置控制器
编辑本页警告:您正在浏览的文档欧宝官网下载appob娱乐下载Symfony 3.0,现已不再维护。
读本页的更新版本用于Syob娱乐下载mfony 6.2(当前稳定版本)。
前置控制器
到目前为止,我们的应用程序很简单,因为只有一个页面。为了让事情变得有趣一点,让我们疯狂地添加另一页来告别:
1 2 3 4 5 6 7 8 9 10
/ /框架/ bye.phprequire_once__DIR__.“/供应商/ autoload.php”;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;$请求=请求::createFromGlobals ();$响应=新响应(“再见!”);$响应->send ();
正如您自己所看到的,许多代码与我们为第一页编写的代码完全相同。让我们提取可以在所有页面之间共享的公共代码。代码共享听起来像是创建我们第一个“真正的”框架的好计划!
PHP进行重构的方法可能是创建一个包含文件:
1 2 3 4 5 6 7 8
/ /框架/ init.phprequire_once__DIR__.“/供应商/ autoload.php”;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;$请求=请求::createFromGlobals ();$响应=新反应();
让我们来看看它的实际情况:
1 2 3 4 5 6 7
/ /框架/ index . phprequire_once__DIR__.' / init.php ';$输入=$请求->get (“名字”,“世界”);$响应->setContent (sprintf (“你好% s”,:$输入ENT_QUOTES,“utf - 8”)));$响应->send ();
在“再见”页面:
1 2 3 4 5
/ /框架/ bye.phprequire_once__DIR__.' / init.php ';$响应->setContent (“再见!”);$响应->send ();
我们确实将大部分共享代码移到了一个中心位置,但感觉不像是一个好的抽象,不是吗?我们仍然有send ()
方法,我们的页面看起来不像模板,我们仍然不能正确地测试这段代码。
此外,添加一个新页面意味着我们需要创建一个新的PHP脚本,该脚本的名称将通过URL (http://127.0.0.1:4321/bye.php
): PHP脚本名和客户端URL之间有一个直接的映射。这是因为请求的分派是由web服务器直接完成的。为了获得更好的灵活性,将这个调度移到我们的代码中可能是个好主意。这可以通过将所有客户端请求路由到单个PHP脚本轻松实现。
提示
将单个PHP脚本公开给最终用户是一种称为“前端控制器".
这样的脚本可能如下所示:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/ /框架/ front.phprequire_once__DIR__.“/供应商/ autoload.php”;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;$请求=请求::createFromGlobals ();$响应=新反应();$地图=数组(' /你好'=>__DIR__.' / hello.php ',' /再见'=>__DIR__.' / bye.php ',);$路径=$请求->getPathInfo ();如果(收取($地图[$路径))) {需要$地图[$路径];}其他的{$响应->setStatusCode (404);$响应->setContent (“没有找到”);}$响应->send ();
这是一个新的例子hello.php
脚本:
1 2 3
/ /框架/ hello.php$输入=$请求->get (“名字”,“世界”);$响应->setContent (sprintf (“你好% s”,:$输入ENT_QUOTES,“utf - 8”)));
在front.php
脚本,美元的地图
关联URL路径和相应的PHP脚本路径。
作为奖励,如果客户端请求的路径没有在URL映射中定义,我们将返回一个自定义404页面;你现在可以控制你的网站了。
要访问页面,现在必须使用front.php
脚本:
http://127.0.0.1:4321/front.php/hello?name=Fabien
http://127.0.0.1:4321/front.php/bye
/你好
而且/再见
是页面路径.
提示
大多数web服务器,如Apache或nginx能够重写传入的url并删除前端控制器脚本,以便您的用户能够键入http://127.0.0.1:4321/hello?name=Fabien
,看起来好多了。
诀窍在于要求::getPathInfo ()
方法,该方法通过删除前端控制器脚本名称及其子目录来返回请求的路径(仅在需要时—参见上面的技巧)。
提示
你甚至不需要设置一个web服务器来测试代码。相反,替换$request = request::createFromGlobals();
调用像这样的东西$request = request::create('/hello?name=Fabien');
其中参数是要模拟的URL路径。
现在web服务器总是访问相同的脚本(front.php
)对于所有页面,我们可以通过将所有其他PHP文件移出web根目录来进一步保护代码:
1 2 3 4 5 6 7 8 9 10 11
├──composer。Json├──composer。页面锁├──src│└──│├──hello.php│└──bye.php├──供应商│└──autoload.php└──web└──front.php
现在,配置您的web服务器根目录指向web /
所有其他文件都不能从客户端访问了。
要在浏览器中测试更改(http://localhost:4321/hello/?name=Fabien
),运行PHP内置服务器:
1
$ php -S 127.0.0.1:4321 -t web/ web/front.php
请注意
要使这个新结构工作,您必须调整各种PHP文件中的一些路径;这些更改留给读者作为练习。
每一页中重复的最后一件事是调用setContent ()
.我们可以将所有页面转换为“模板”,只需回显内容并调用setContent ()
直接从前端控制器脚本:
12 3 4 5 6 7 8 9 10 11 12 13 14 15
/ / example.com/web/front.php/ /……$路径=$请求->getPathInfo ();如果(收取($地图[$路径])) {ob_start();包括$地图[$路径];$响应->setContent (ob_get_clean ());}其他的{$响应->setStatusCode (404);$响应->setContent (“没有找到”);}/ /……
和hello.php
脚本现在可以转换为模板:
1 2 3 4
<!——example.com/src/pages/hello.php——- > < ?php$的名字=$请求->get (“名字”,“世界”)? >你好<?php回声:$的名字ENT_QUOTES,“utf - 8”)? >
我们有了框架的第一个版本:
12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/ / example.com/web/front.phprequire_once__DIR__.“/ . . /供应商/ autoload.php”;使用ob娱乐下载\组件\HttpFoundation\请求;使用ob娱乐下载\组件\HttpFoundation\响应;$请求=请求::createFromGlobals ();$响应=新反应();$地图=数组(' /你好'=>__DIR__.“/ . . / src /页面/ hello.php”,' /再见'=>__DIR__.“/ . . / src /页面/ bye.php”,);$路径=$请求->getPathInfo ();如果(收取($地图[$路径])) {ob_start();包括$地图[$路径];$响应->setContent (ob_get_clean ());}其他的{$响应->setStatusCode (404);$响应->setContent (“没有找到”);}$响应->send ();
添加新页面分为两个步骤:在映射中添加一个条目,并在中创建一个PHP模板src /页面/
.方法从模板中获取请求数据美元的请求
变量和调整响应头美元的反应
变量。
请注意
如果您决定在这里停止,您可能可以通过将URL映射提取到配置文件来增强您的框架。