【问题标题】:MVC - Looking for a better way to get from URL to viewMVC - 寻找从 URL 到视图的更好方法
【发布时间】:2016-06-22 17:34:38
【问题描述】:

下面的例子展示了我目前是如何做事的。

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。它设置页面的元数据,设置站点结构,并包含$page 变量在index_controller.php 中设置的任何文件

使用上面的示例,如果有人访问 mysite.com/category/booksindex_controller.php 将查看图书类别是否存在,如果存在,category.inc.php 将被包括在内。

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

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

如何使用类和/或函数而不是我当前使用的所有包含将用户从 URL 获取到视图?

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

我们将不胜感激任何帮助、意见或建议。

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

【问题讨论】:

  • 这是一个相当广泛的问题 - 它几乎读作“我如何构建 MVC 框架?”问题的标题暗示了一些更具体的东西,但你从来没有真正澄清这一点。如果您还没有,请查看help center,因为了解此站点与普通论坛有何不同非常重要:您不是在开始对话,因此您需要专注于特定问题,并且确保它是网站的“主题”。
  • @IMSoP 抱歉,这个问题很笼统。我对其进行了编辑以试图澄清实际问题。希望这有助于更好地理解我在寻找什么。

标签: php model-view-controller


【解决方案1】:

通过一个小技巧和.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;
    }
}

【讨论】:

  • 嗨 :) 这里有很多代码,但解释不多(即使在代码中的 cmets 中)。什么是“小技巧”?您认为代码的哪一部分与该问题特别相关? (我意识到这个问题本身非常广泛......)
  • 嗨!对不起这是我的错。所以这里的技巧我使用.htaccess 将请求 uri 作为 get 参数传递,然后在 php.ini 中将其拆分。有了这个,我得到了一个数组。数组的第一项声明它应该包含哪个控制器(您可以设置默认控制器,但我使用.htaccess 在未设置任何内容时重定向)。如果选择的Controller和其他所有项都是该方法的参数,则第二项是方法。
  • @Nergal 谢谢你的回答!这看起来比我现在做的事情要干净得多。在我的代码中使用你的部分示例将帮助我走上我正在寻找的道路。
  • @Jay 欢迎您。如果您需要更多帮助,请发表评论。此外,如果这是您正在寻找的答案,请接受它。
猜你喜欢
  • 2015-11-24
  • 1970-01-01
  • 2013-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-11
相关资源
最近更新 更多