MVC - 寻找从URL到视图的更好方法

时间:2016-06-22 17:34:39

标签: php model-view-controller

以下示例显示了我目前的工作方式。

index.php包括index_controller.php然后是index_template.php。

index_controller.php

$uri = explode('/', $_SERVER['REQUEST_URI']);
$action = $uri[1];
$call = $uri[2];

$tmp = explode('?', $call);
$call = $tmp[0];

$call = preg_replace('/-/', ' ', $call);

switch ($action) {
    case "about":
        $page = "about.inc.php";
        $title = "About Us";
        $description = "Description of page";
        break;
    case "category":
        try {
            //PDO query to make sure category ($call) exists
        }
        catch (PDOException $e) {
            logError($e->getMessage());
        }
        if (query->rowCount() < 1) {
            $page = "404.inc.php";
            $title = "404 Error";
        }
        else {
            //Meta information for selected category pulled from DB and put into variables.
            $page = "category.inc.php";
        break;
    default:
        $page = "404.inc.php";
        $title = "404 Error";
}

上面的示例显示了switch语句中大约12个不同页面选项中的2个。一个简单的请求(约)和一个更复杂的请求(类别)。

index_template.php包含我的所有头部,正文和页脚HTML。它设置页面的元数据,设置网站结构,并包含$pageindex_controller.php变量设置的任何文件

使用上面的示例,如果有人访问 mysite.com/category/books index_controller.php,将查看图书类别是否存在以及是否包含category.inc.php

category.inc.php执行另一个PDO查询以获取显示所选类别的项目列表所需的所有项目和信息。它还包括一个模板文件,用于构建返回项目的显示。

我正在尝试实现MVC类型结构(不使用像Codeigniter或CakePHP这样的框架),但我真的没有让模型结束。

如何使用类和/或函数从URL到视图,而不是我目前使用的所有包含?

如果您觉得我没有很好地解释提到的其他文件,我也可以提供这些文件中的代码示例。

非常感谢任何帮助,意见或建议。

编辑:根据以下评论澄清问题。

1 个答案:

答案 0 :(得分:0)

通过一个小技巧和.htaccess,你可以更容易。

我在自制的基于MVC的应用程序中使用此方法。您可以复制粘贴整个代码或只使用其中的一部分。主要逻辑在Bootstrap类中。

的.htaccess

Options -Indexes

RewriteEngine On
RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l

RewriteRule ^(.+)$ index.php?url=$1 [QSA,L]
RewriteRule ^$ /news [R]

的index.php

require 'brInit.php';

$app = new \brInclude\brClasses\mvc\Bootstrap();

我使用brInit自动包含类并包含我的配置文件

bootstrap.php中

class Bootstrap {
    private $url = array();
    /** @var Controller $controller */
    private $controller;

    function __construct(){
        try {
            $this->_getUrl();

            $this->_loginUser();

            if(!$this->_setController($this->url[0]))
                throw new Exception('404');

            if(!$this->_executeControllersMethod())
                throw new Exception('404');
        } catch(Exception $e){
            $this->_error($e->getMessage());
        }
    }

    private function _error($msg){
        $this->url = array('Error', 'error', $msg);
        $this->_setController($this->url[0]);
        $this->_loginUser();
        $this->_executeControllersMethod();
    }

    private function _getUrl(){
        if(isset($_GET['url']))
            $this->url = explode('/', rtrim($_GET['url'], '/'));
        else
            $this->url = array('news');

        unset($_GET['url']);
    }

    private function _setController($name){
        $path = 'brInclude/brMVC/controller/';
        if(!file_exists($path)) return false;

        $url = ucfirst($name) . 'Controller';
        $namespace = str_replace('/', '\\', $path);
        $file = $path . $url . '.php';
        if(!file_exists($file)) return false;

        $classWithNamespace = $namespace . $url;
        $this->controller = new $classWithNamespace;
        $this->controller->view->name = $name;
        return true;
    }

    private function _loginUser(){
        $model = new UserModel();
        $user = $model->login();
        Controller::$user = $user;
    }

    private function _executeControllersMethod(){
        if(isset($this->url[1])){
            if(method_exists($this->controller, $this->url[1])){
                $count = count($this->url);
                if($count > 2)
                    call_user_func_array(
                        array($this->controller, $this->url[1]),
                        array_slice($this->url, 2)
                    );
                else
                    $this->controller->{$this->url[1]}();
            } else {
                return false;
            }
        } else {
            $this->controller->index();
        }
        return true;
    }

    public static function isLoginRequired(){
        return self::$loginRequired;
    }
}