Pap*_*lie 11 php subdomain model-view-controller url-routing
谁定义了要重定向到移动版本的URL?
让我们以twitter为例:
https://twitter.com
- >重定向移动https://dev.twitter.com
- >不重定向移动在一个负责规则重定向的MVC应用程序中?
可能全部www
都有重定向到移动设备?
一种方法是使用
.htaccess
或等效工具从服务器重定向(apache 不是唯一的网络服务器)并强制重定向。其他答案已经涵盖了。但有一种不同的方法。实际上会利用 MVC 的一种:根本不重定向。
在正确实现的 MVC 中,视图实例将包含所有 UI 逻辑。他们将从模型层获取数据(“如何”构成了 Model2、MVP 和 MVVM 之间的大部分区别),决定从哪些模板组装响应,或者即使响应除了 HTTP 位置标头之外还需要其他内容。
移动版本和桌面版本之间的差异将包含在视图实例中,并由控制器辅助,在正确的 MVC 结构中,控制器只会更改模型层和当前视图的状态。它所做的改变应该取决于用户的输入。
以下代码将是bootstrap.php
or的一部分init.php
:
// the request instance acts like abstraction for all the user input
$request = new Request;
$request->setUri();
// instantiate the routing mechanism
$router = new Router( new RouteBuilder );
$router->import('/path/to/config.file');
// apply rules from router so that request instance now
// contains the parsed values from URI
$router->route( $request );
// handling of model layer
$serviceFactory = new ServiceFactory;
// since in MVC the controllers are closely tied to views
// (1 controller for 1 view), usually it is convenient to use same class names
$resource = $request->getParameter('resource');
// instantiation of view and controller
$class = '\\View\\' . $resource;
$view = new {$class}( $serviceFactory );
$class = '\\Controller\\' . $resource;
$controller = new {$class}( $serviceFactory, $view);
// i find it convenient to have controller's action be made from
// both REQUEST_METHOD and command name
$action = $request->getMethod() . $request->getParameter('command');
// run it all
$controller->{$action}( $request );
echo $view->render();
Run Code Online (Sandbox Code Playgroud)
这样,当执行命中控制器的操作时,就会为其提供一个完全准备好的实例Request
。所述实例确定有关用户设备的详细信息并提供用于读取这些详细信息的简单界面。
控制器还可以访问模型层和当前视图,这两者都是通过构造函数注入的。
最直接的方法是让控制器改变当前视图的状态。
namespace Conroller;
class SomeThing
{
public function getUserDetails( $request )
{
if ( $request->isFromMobile() )
{
$this->view->adjustFor( $request->getDeviceType() );
}
$community = $this->serviceFactory->create('Community');
$community->loadUser( $request->getParameter('id'));
}
}
Run Code Online (Sandbox Code Playgroud)
本例中的方法adjustFor()
通知当前视图实例,它将需要使用适用于某些非默认设备的模板。
这种方法有一个非常重要的缺点:它违反了OCP from SOLID 原则(对于懒人:简短版本),因为如果您决定为现有项目添加移动版本,则必须重写每个控制器方法。
虽然下面的代码相对容易理解,但它有一点缺陷:
$resource = $request->getParameter('resource');
// instantiation of view and controller
$class = '\\View\\' . $resource;
$view = new {$class}( $serviceFactory );
Run Code Online (Sandbox Code Playgroud)
即使您只需要提供 HTML 和 JSON/XML 响应,它也会开始崩溃。视图开始IF
在整个代码中积累相同的重复。这是一个明显的迹象,表明您应该使用多态性,并且这些行将是执行此操作的位置。
您可以使用以下代码来代替上面显示的代码:
$resource = $request->getParameter('resource');
$class = '\\View\\' . $request->getDeviceType . $resource;
$view = new {$class}( $serviceFactory );
Run Code Online (Sandbox Code Playgroud)
现在,当您拥有移动/桌面应用程序时,您有两个类:\View\DekstopSomething
和\View\MobileSomething
。它们每个都可以具有单独的逻辑,并从模型层请求完全不同的数据。
同时,其余代码与输出形式完全解耦。
您最好选择这种方法,而不是使用服务器重定向,原因如下:
您的应用程序变得独立于服务器软件
并非所有地方都会有 Apache(高负载站点通常使用 Nginx 或 Lighttpd),即使您有 Apache,您使用mod_rewrite 的能力也将取决于服务器的配置。
站点中所有链接的统一方案
无论您使用什么设备,查看某些新闻项目的链接始终相同。它使 URL 的共享和书签变得更加容易。
单点变化
这种方法允许您最初为桌面用户创建网站,然后添加移动/平板电脑支持,而无需重写任何现有代码。