11

モバイル版にリダイレクトされるURLを誰が定義しますか?

例としてTwitterを取り上げましょう。

  • https://twitter.com ->モバイルリダイレクト
  • https://dev.twitter.com->モバイルをリダイレクトしない

ルールのリダイレクトを担当するMVCアプリケーションでは?
すべてがwwwモバイルデバイスへのリダイレクトを持っている可能性がありますか?

4

4 に答える 4

4

1つの方法は、.htaccessまたは同等のツールを使用してサーバーからリダイレクトし(ApacheだけがWebサーバーではありません)、リダイレクトを強制することです。それはすでに他の答えでカバーされています。しかし、には別のアプローチがあります。実際にMVCを利用するもの:リダイレクトしないでください。

MVCデザインパターンの簡単な背景

正しく実装されたMVCでは、ビューインスタンスにすべてのUIロジックが含まれます。モデルレイヤーからデータを取得し(「方法」がModel2、MVP、MVVMの違いの大部分を構成します)、応答をアセンブルするテンプレートを決定します。応答にHTTPロケーションヘッダー以外のものが必要な場合でも決定します。

モバイルバージョンとデスクトップバージョンの違いは、コントローラーの支援を受けてビューインスタンスに含まれます。コントローラーは、正しいMVC構造では、モデルレイヤーと現在のビューの状態のみを変更します。どのような変更を加えるかは、ユーザー入力によって異なります。

すべてを設定する

次のコードは、bootstrap.phpまたはの一部になり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();

このように、実行がコントローラーのアクションにヒットすると、完全に準備されたのインスタンスが提供されます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'));
    }
}

この場合のadjustFor()メソッドは、現在のビューインスタンスに、デフォルト以外のデバイス用のテンプレートを使用する必要があることを通知します。

このアプローチには非常に重要な欠点が1つあります。既存のプロジェクトにモバイルバージョンを追加する場合は、各コントローラーメソッドを書き直す必要があるため、SOLIDの原則(怠惰な人の場合:短いバージョン)のOCPに違反します。

..より良い方法があります

次のコードは比較的理解しやすいですが、少し欠陥があります。

$resource = $request->getParameter('resource');

// instantiation of view and controller
$class = '\\View\\' . $resource;
$view = new {$class}( $serviceFactory );

HTMLとJSON/XMLの両方の応答を提供するだけでよい場合でも、機能が低下し始めます。ビューは、コード全体で同じ繰り返しを蓄積し始めIFます。これは、ポリモーフィズムを使用する必要があることを明確に示しており、これらの行がそれを実行する場所になります。

上に示したコードの代わりに、次のようなものを使用できます。

$resource = $request->getParameter('resource');

$class = '\\View\\' . $request->getDeviceType . $resource;
$view = new {$class}( $serviceFactory );

これで、モバイル/デスクトップアプリケーションを使用している場合、次の2つのクラスが\View\DekstopSomethingあり\View\MobileSomethingます。それぞれが個別のロジックを持ち、モデルレイヤーから完全に異なるデータを要求できます。

その間、コードの残りの部分は出力フォームから完全に切り離されます。

メリットは何ですか?

サーバーリダイレクトを使用する代わりに、このアプローチを選択する方がよい理由はいくつかあります。

  1. アプリケーションはサーバーソフトウェアから独立します

    Apacheを使用できる場所がどこにでもあるわけではなく(高負荷サイトでは代わりにNginxまたはLighttpdを使用することがよくあります)、Apacheを使用している場合でも、mod_rewriteを使用できるかどうかはサーバーの構成によって異なります。

  2. サイト内のすべてのリンクの統一スキーム

    一部のニュースアイテムを表示するためのリンクは、使用するデバイスに関係なく、常に同じです。これにより、URLの共有とブックマークがはるかに簡単になります。

  3. 単一の変化点

    このアプローチでは、最初にデスクトップユーザー向けのサイトを作成してから、既存のコードを書き直すことなくモバイル/タブレットのサポートを追加できます。

また、MVCのコンテキストでのモデルレイヤーアクセス制御の実装に関する主題に関する2つの古い投稿を読むことにも興味があるかもしれません。

于 2012-12-25T13:25:20.993 に答える
2

モバイルユーザーをどのように検出するかによって異なります。これは、Webサーバーが書き換えルールを使用して実行できます。これは、PHPコードのユーザーエージェントスクリプトを介して検出できます。この場合、コントローラーによって検出されます。非常に多くのオプションがあるため、混乱を招く可能性があります。グーグルはこれについてたくさんの詳細を持っています。

例を書き直します:

RewriteCond %{HTTP_USER_AGENT}  ^.*iPhone.*
RewriteRule ^(.*)$         m.site.com/$1
于 2012-12-25T05:27:37.153 に答える
0

@Supericyが述べているように、ほとんどの場合、フロントエンド(ビュー)が検出を担当します。これは、その名前が示すように、ユーザーに表示されるものだからです。

たとえば、モバイル検出クラスheader()を使用する場合、関数を使用する場合は、index.phpまたは同様のファイルの先頭に書き込むだけです。

<?php
include 'Mobile_Detect.php';
$detect = new Mobile_Detect();

if ($detect->isMobile()) {
    // Any mobile device. Do stuff
} else {

}

?>

モバイル検出クラスページhttps://github.com/serbanghita/Mobile-Detectには他にも例があります。あなたは本当にデバイスに固有のものを得ることができます。

これを達成する方法は他にもたくさんありますが、これは私の意見では最も簡単です。

于 2012-12-25T05:30:59.003 に答える
0

モバイルデバイスのユーザーを検出することは、すべてのトラフィックを支配することになっているため、サーバーに与えるのが最善です。コードが異なるWebルートに残っている場合、またはデスクトップデバイスとモバイルデバイスを使用しているユーザーに同じページを表示する必要がない場合は、問題を解決するapache構成の一部を次に示します。必ずhttp://detectmobilebrowsers.com/にアクセスして、新しいバージョンのモバイル検出正規表現を入手してください。

# if already mobile - skip this (usually there are will be another config for mobile)
RewriteCond %{HTTP_HOST} !^mobile\.
# put all sites you don't want to redirect here, or compose a regex that will match sites
RewriteCond %{HTTP_HOST} !(dev.twitter.com) 

# taken from http://detectmobilebrowsers.com/
RewriteCond %{HTTP_USER_AGENT} (android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od|ad)|iris|kindle|lge\ |maemo|midp|mmp|netfront|opera\ m(ob|in)i|palm(\ os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows\ (ce|phone)|xda|xiino [NC,OR]
RewriteCond %{HTTP_USER_AGENT} ^(1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a\ wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r\ |s\ )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1\ u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp(\ i|ip)|hs\-c|ht(c(\-|\ |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac(\ |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt(\ |\/)|klon|kpt\ |kwc\-|kyo(c|k)|le(no|xi)|lg(\ g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-|\ |o|v)|zz)|mt(50|p1|v\ )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v\ )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-|\ )|webc|whit|wi(g\ |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-) [NC]

# rewrite only sites.
RewriteCond %{HTTP_HOST} (\.|)([^\.]+\.[^\.0-9]+)$

#redirect to mobile
RewriteRule ^(.*)$ http://mobile.twitter.com$1 [L,NS]
于 2012-12-25T08:37:38.230 に答える