web-dev-qa-db-ja.com

MVCコントローラーの例

私は、アプリケーションでMVCアプローチを使用する方法と理由について多くのことを読んでいます。私はモデルの例を見て理解しましたが、ビューの例を見て理解しました。コントローラーの十分な例を見たいと思います。 (in PHP可能であれば、ただし、どの言語でも役立ちます)

ありがとうございました。

PS:どのコントローラーをどのように使用するかを決定するindex.phpページの例を見ることができたら素晴らしいと思います。

編集: 私はコントローラーの仕事が何であるかを知っていますが、OOPでこれを達成する方法を本当に理解していません。

39
BDuelz

リクエストの例

このようなものをindex.php

<?php

// Holds data like $baseUrl etc.
include 'config.php';

$requestUrl = 'http://'.$_SERVER['HTTP_Host'].$_SERVER['REQUEST_URI'];
$requestString = substr($requestUrl, strlen($baseUrl));

$urlParams = explode('/', $requestString);

// TODO: Consider security (see comments)
$controllerName = ucfirst(array_shift($urlParams)).'Controller';
$actionName = strtolower(array_shift($urlParams)).'Action';

// Here you should probably gather the rest as params

// Call the action
$controller = new $controllerName;
$controller->$actionName();

本当に基本ですが、あなたはアイデアを手に入れました...

シンプルなコントローラーの例(controllers/login.php):

<?php    

class LoginController
{
    function loginAction()
    {
        $username = $this->request->get('username');
        $password = $this->request->get('password');

        $this->loadModel('users');
        if ($this->users->validate($username, $password))
        {
            $userData = $this->users->fetch($username);
            AuthStorage::save($username, $userData);
            $this->redirect('secret_area');
        }
        else
        {
            $this->view->message = 'Invalid login';
            $this->view->render('error');
        }
    }

    function logoutAction()
    {
        if (AuthStorage::logged())
        {
            AuthStorage::remove();
            $this->redirect('index');
        }
        else
        {
            $this->view->message = 'You are not logged in.';
            $this->view->render('error');
        }
    }
}

ご覧のとおり、コントローラーはアプリケーションの「フロー」、いわゆるアプリケーションロジックを処理します。データの保存と表示は考慮しません。むしろ、(現在のリクエストに応じて)必要なすべてのデータを収集し、ビューに割り当てます...

これは私が知っているどのフレームワークでも動作しないことに注意してください。しかし、関数が何をすべきかを知っていると確信しています。

62
Franz

UIの3つの画面、ユーザーが検索条件を入力する画面、一致するレコードの概要のリストが表示される画面、およびレコードが選択されると編集用に表示される画面を想像してください。最初の検索に関連するいくつかのロジックがあります

if search criteria are matched by no records
    redisplay criteria screen, with message saying "none found"
else if search criteria are matched by exactly one record
    display edit screen with chosen record
else (we have lots of records)
    display list screen with matching records

そのロジックはどこに行くべきですか?確かにビューやモデルにはありませんか?したがって、これはコントローラーの仕事です。コントローラーは、基準を取得し、検索用のModelメソッドを呼び出すことも担当します。

2
djna
<?php

class App {
    protected static $router;

    public static function getRouter() {
        return self::$router;
    }

    public static function run($uri) {
        self::$router = new Router($uri);

        //get controller class
        $controller_class = ucfirst(self::$router->getController()) . 'Controller';
        //get method
        $controller_method = strtolower((self::$router->getMethodPrefix() != "" ? self::$router->getMethodPrefix() . '_' : '') . self::$router->getAction());

        if(method_exists($controller_class, $controller_method)){
            $controller_obj = new $controller_class();
            $view_path = $controller_obj->$controller_method();

            $view_obj = new View($controller_obj->getData(), $view_path);
            $content = $view_obj->render();
        }else{
            throw new Exception("Called method does not exists!");
        }

        //layout
        $route_path = self::getRouter()->getRoute();
        $layout = ROOT . '/views/layout/' . $route_path . '.phtml';
        $layout_view_obj = new View(compact('content'), $layout);
        echo $layout_view_obj->render();
    }

    public static function redirect($uri){
        print("<script>window.location.href='{$uri}'</script>");
        exit();
    }
}
0
David
<?php
class Router {

    protected $uri;

    protected $controller;

    protected $action;

    protected $params;

    protected $route;

    protected $method_prefix;

    /**
     * 
     * @return mixed
     */
    function getUri() {
        return $this->uri;
    }

    /**
     * 
     * @return mixed
     */
    function getController() {
        return $this->controller;
    }

    /**
     * 
     * @return mixed
     */
    function getAction() {
        return $this->action;
    }

    /**
     * 
     * @return mixed
     */
    function getParams() {
        return $this->params;
    }

    function getRoute() {
        return $this->route;
    }

    function getMethodPrefix() {
        return $this->method_prefix;
    }

        public function __construct($uri) {
            $this->uri = urldecode(trim($uri, "/"));
            //defaults
            $routes = Config::get("routes");
            $this->route = Config::get("default_route");
            $this->controller = Config::get("default_controller");
            $this->action = Config::get("default_action");
            $this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : '';


            //get uri params
            $uri_parts = explode("?", $this->uri);
            $path = $uri_parts[0];
            $path_parts = explode("/", $path);

            if(count($path_parts)){
                //get route
                if(in_array(strtolower(current($path_parts)), array_keys($routes))){
                    $this->route = strtolower(current($path_parts));
                    $this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : '';
                    array_shift($path_parts);
                }

                //get controller
                if(current($path_parts)){
                    $this->controller = strtolower(current($path_parts));
                    array_shift($path_parts);
                }

                //get action
                if(current($path_parts)){
                    $this->action = strtolower(current($path_parts));
                    array_shift($path_parts);
                }

                //reset is for parameters
                //$this->params = $path_parts;
                //processing params from url to array
                $aParams = array();
                if(current($path_parts)){ 
                    for($i=0; $i<count($path_parts); $i++){
                        $aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null;
                        $i++;
                    }
                }

                $this->params = (object)$aParams;
            }

    }
}
0
David
  1. フォルダー構造を作成する
  2. .htaccessと仮想ホストのセットアップ
  3. 構成配列を作成する構成クラスを作成します

コントローラ

  1. ゲッターを使用して、非静的に保護されたルータークラスを作成する
  2. Config include&autoloadおよびincludeパス(lib、controlelrs、models)でinit.phpを作成します
  3. ルート、デフォルト値(ルート、コントローラー、アクション)を含む構成ファイルを作成する
  4. ルーターに値を設定-デフォルト
  5. Uriパスを設定し、uriを展開し、route、controller、action、params、process paramsを設定します。
  6. Uriを渡すことでアプリケーションを実行するアプリクラスを作成します-(保護されたルーターobj、funcを実行)
  7. コントローラーの親クラスを作成して、他のすべてのコントローラー(保護されたデータ、モデル、パラメーター-非静的)を継承します。データ、コンストラクターのパラメーターを設定します。
  8. コントローラを作成し、上記の親クラスで拡張し、デフォルトのメソッドを追加します。
  9. Run関数でコントローラークラスとメソッドを呼び出します。メソッドにはプレフィックスが必要です。
  10. 存在する場合はメソッドを呼び出します

視聴回数

  1. ビューを生成する親ビュークラスを作成します。 (データ、パス)デフォルトのパス、コントローラの設定、funcsをレンダリングして、完全なテンポラルパスを返します(非静的)
  2. Ob_start()、ob_get_cleanを使用してレンダリング関数を作成し、コンテンツを返してブラウザに送信します。
  3. データを解析してクラスを表示するようにアプリクラスを変更します。パスが返される場合は、ビュークラスにもパスします。
  4. Layouts..layoutはルーターに依存します。レイアウトhtmlを再解析して表示およびレンダリングします
0
David