0

MVC がどのように機能するかを学習する手段として、PHP で基本的な MVC 構造化 CMS を作成しています (したがって、実際に事前に構築されたエンジンを使用していません)。私は、このチュートリアルhereと非常によく似た構造の基本的なバージョンを使用しています。ただし、テンプレート クラスの必要性をバイパスして、ビューが自動的に読み込まれるようにしたいと考えています。これが強く推奨される場合は、テンプレートの概念に固執します (なぜそれが必要なのかを誰かが説明できれば、私はそれを大いに感謝します)。

    public function loader() {
        /*** check the route ***/
        $this->getPath();

        /*** if the file is not there diaf ***/
        if (is_readable($this->controller_path) == false) {
            $this->controller_path = $this->path.'/controller/error404.php';
            $this->action_path = $this->path.'/view/error404.php';
        }

        /*** include the path files ***/
        include $this->controller_path;
        include $this->action_path;

        /*** a new controller class instance ***/
        $class = $this->controller . 'Controller';
        $controller = new $class($this->registry);

        /*** check if the action is callable ***/
        if (is_callable(array($controller, $this->action)) == false) {
            $action = 'index';
        } else {
            $action = $this->action;
        }
        $controller->$action();
    }

    /**
    *
    * @get the controller
    *
    * @access private
    *
    * @return void
    *
    */
    private function getPath() {

        /*** get the route from the url ***/
        $route = (empty($_GET['rt'])) ? '' : $_GET['rt'];

        if (empty($route)) {
            $route = 'index';
        } else {
            /*** get the parts of the route ***/
            // mywebsite.com/controller/action
            // mywebsite.com/blog/hello
            $parts = explode('/', $route);
            $this->controller = $parts[0];
            if(isset( $parts[1])) {
                $this->action = $parts[1];
            }
        }
        if( ! $this->controller ) { $this->controller = 'index'; }
        if( ! $this->action ) { $this->action = 'index'; }

        /*** set the file path ***/
        $this->controller_path = $this->path .'/controller/'. $this->controller . '.php';
        $this->action_path = $this->path .'/view/'. $this->controller . '/'. $this->action . '.php';
    }

これにより、コントローラーによって指定された変数をビュー ファイルが読み込む$this->registry->template->blog_heading = 'This is the blog Index';ことができなくなります (チュートリアルの Web サイトには、これについてのより良いデモがあります)。基本的に私が求めているのは、どのように template.class をロード関数に移行するのですか?

4

3 に答える 3

3

「ビューはただのテンプレートにすぎない」という非常に一般的な誤解は、Ruby-on-Rails と、壊れた ORM-Template-Adapter に従うものによってほとんど永続化されています。Model-View-Controller として実装されているものを真顔で参照することはできません...

ビューは、MVC および MVC にインスパイアされたデザイン パターン パターンのプレゼンテーション ロジックを処理することになっています。複数のテンプレートをジャグリングする機能を備えたオブジェクトになります。

Web アプリケーションに使用する MVC にインスパイアされたパターン (PHP で従来の MVC を実装することは不可能) に応じて、ビューはコントローラーのような構造 (MVP および MVVM パターン) からデータを受け取るか、情報を直接要求できます。モデル層から (Model2 MVC および HMVC パターン)。個人的には、モデル レイヤーからデータを取得するアクティブ ビューを好みます。

このようなPSコードは、デメテルの出血$this->registry->template->blog_headingを引き起こします。

PPS 純粋な php テンプレートを実装する方法については、この記事をお読みください。

于 2012-07-24T10:56:52.957 に答える
1

現時点ではあまり役に立たないことは承知していますが、数か月前に同じ問題が発生しました。これは、私が構築したフレームワークに基づいています。

https://github.com/andyhmltn/Cherry-Framework-Blog-Example/

I'm not exactly sure where or how it does it as I haven't actually looked at it in a while, but take a poke around and the code that loads the controller, sets the variables and then loads the view is probably in the library folder. It allows you to do this:

/** Controller **/
class ExampleController extends Controller {
    public function index() {
        $helloworld = 'Hello world';
        $this->set('hello_world', $helloworld);
        #Renders view automatically
    }
}

/** View **/
echo $hello_world;
于 2012-07-24T08:54:05.023 に答える
1

私が開発した私自身の MVC では、ビューの読み込みはあなたが持っているものと同様に機能しますが、リンク先の例よりもはるかに簡単な方法です。(私が最初に MVC を学ぼうと決心したときにその例を見ましたが、それが私を混乱させたことを覚えています x;.

基本的に、ファイルが存在すると判断した後は、ファイルを要求するだけです (はい、必要です。この場合、ファイルが見つからないことがスクリプトの実行を停止する正当な理由だと思います)。

だから..テンプレートクラス全体の代わりに(そして、私があなたの質問を避けて、ベースから離れすぎていないことを願っています.これは、コントローラーがビューファイルを開く簡単な例です.

<?php
class Pizza_Shop_Controller extends Base_Controller
{
    public function index()
    {
        $data['users'] = array('bob','lisa','bertha');
        $data['some_string'] = "Whoa I'm a string!";

        $this->render_view('index',$data);
    }

    public function contact()
    {
        if($_POST)
        {
            Contact::process($_POST);
            return $this->render_view('contact_success');
        }
        else
        {
            return $this->render_view('contact_form');
        }
    }


}

class Base_Controller
{

    protected function render_view($view_name,$data = array())
    {
        /*
         * I also think render_view should take care of loading the layout, and then inject the content into the middle of the layout file,
         * so that you aren't trapping yourself to a specific layout, and repeating the header and footer inside of every view file
        */

        extract($data); //places all $data variables into the local scope.. very clean and ezy ;].
        require($this->root_directory.DS."$view_name.php");
    }

    /**********************************/
    public function _no_action($view_name) //Called if there is no corresponding action
    {
        /* You can use method_exists to test if a method exists within the controller, if it does not exist,
         * you can then call this function, and pass it the name of the view that is attempting to be opened
         */
         if($this->view_exists($view_name))
         {
            $this->render_view($view_name,$data);
         }
         else
         {
            $this->render404();
         }
    }

}
于 2012-07-24T08:40:58.627 に答える