【问题标题】:Is this the right way to set up an MVC framework?这是建立 MVC 框架的正确方法吗?
【发布时间】:2012-09-04 00:12:30
【问题描述】:

因此,我一直在研究并致力于构建自己的 MVC 框架,但不断遇到 6 种不同的实现方式,我想知道我目前的做法是否正确。是的,我知道我可以使用 Zend 或其他类似的工具,但我真的想了解框架是如何工作的,而不仅仅是使用其他人的。

这是我的索引文件的简单版本:

if(isset($_GET['url']))
{
    $url = strtolower($_GET['url']);
}
else
{
    $url = 'home';
}

switch($url)  // Select the controller based on the GET var in the url
{
    case 'home': include(ROOT_DIR . 'app/controllers/homeCon.php'); // This page has the link to the DB test page on it
        break;
    case 'dbtest': include(ROOT_DIR . 'app/controllers/dbTestCon.php');
        break;
    default: include(ROOT_DIR . 'app/views/error404View.php');
}

这是我的 dbTestCon.php 控制器的简单版本:

if(isset($_POST['dbSubBtn']))
{
    $model = new DbTestModel();

    if($_POST['firstName'] != '' && $_POST['lastName'] != '')
    {
        $model->submitToDb($_POST['firstName'], $_POST['lastName'])
        $model->displayPage('goodToGo');
    }  
    else
    {
        $model->displayPage('noInput');
    }
}
else
{
    $model->displayPage('normal');
}

这是我的 DbTestModel.php:

class DbTestModel
{
    public function displayPage($version)
    {
        $title = "DB Test Page";
        $themeStylesheetPath = 'public/css/cssStyles.css';

        include(ROOT_DIR . 'app/views/headerView.php');
        include(ROOT_DIR . 'app/views/dbTestView.php');

        switch($version)
        {
            case 'goodToGo':
                include(ROOT_DIR . 'app/views/dbTestSuccessView.php');
                break;
            case 'noInput':
                include(ROOT_DIR . 'app/views/noInputView.php');
                break;
        }
        include(ROOT_DIR . 'app/views/footerView.php');
    }

    public function submitToDb($firstName, $lastName)
    {
        try 
        {
            $db = new PDO("mysql:host=" . DB_HOST . ";dbname=" . DB_NAME, DB_USER, DB_PASS); 
            $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

            $sql = $db->prepare('insert into dbtest(firstName, lastName) values(:firstName, :lastName)');
            $sql->bindParam(':firstName', $firstName);
            $sql->bindParam(':lastName', $lastName);
            $sql->execute();
            $db = null;
        }
        catch(PDOException $e)
        {
            echo "It seems there was an error.  Please refresh your browser and try again. " . $e->getMessage();
        }
    }
}

这是我的 dbTestView.php:

<form name="dbTestForm" id="dbTestForm" method="POST" action="dbtest">
    <label for="firstName">First Name</label>
    <input type="text" name="firstName" id="firstName" />
    <label for="lastName">Last Name</label>
    <input type="text" name="lastName" id="lastName" />
    <input type="submit" name="dbSubBtn" id="dbSubBtn" value="Submit to DB" />
</form>

这个简单的例子可以在我的测试环境中使用,但我担心我会在下一个项目中开始使用它,并在进行到一半时意识到我的框架存在根本性的问题,必须重新开始。感谢您的任何帮助或建议。

【问题讨论】:

标签: php model-view-controller frameworks


【解决方案1】:

不,这不是正确的方法!

  • 路由机制完全不完善:

    在您当前的代码库中,您必须手动注册每个控制器,这显然会使引导阶段(index.php 文件)混乱且容易出错.

  • 你有“模型”渲染模板

    即使在最原始的 MVC 设计模式解释中,这也是错误的。视图应该是包含表示逻辑的实例,而不是由您称为“模型”的东西呈现的模板。

  • 模型是一个层,而不是任何一个类

    MVC 设计模式由两层组成:表示层和模型层。模型层包含所有领域业务逻辑,并通过某种抽象形式与存储进行交互。

  • 不要每次都重新初始化数据库连接。

    每次您需要使用数据库时,您的“模型”都会初始化新的 PDO 实例。相反,您应该只创建一次连接实例并通过构造函数将其传递给每个对象。

  • 停止编写带有隐藏警告和错误消息的代码!

【讨论】:

  • 感谢您的建议。你有什么推荐的教程我可以看看吗?正如我在问题中所说,我发现了大约 6 种不同的方式来构建 MVC 框架......
  • 在 php 中没有很好的 MVC 教程,因为他们中的大多数只是假设 Rails 是一个 MVC 框架(它不是)。相反,我建议您阅读 Martin Fowler 的 GUI Architectures 和所有链接的材料 here(有几堂课用于学习高级 OOP)。此外,您可能会发现我的 thisthis 帖子相关。
【解决方案2】:

在同一个地方进行数据存储(例如模型逻辑)和输出(例如视图逻辑)通常被认为是错误的形式,这发生在 DbTestModel 中。

你可以做大量的重构,但我不会为你拼写出来,因为我最终会写段落。

我强烈建议您阅读 Fabien Potiencer 的博客系列Create your own framework... on top of the Symfony2 Components

即使您不想使用他的组件来帮助构建任何东西,它也应该为您提供一堆好主意。

【讨论】:

  • 我得去看看。感谢您的建议。
猜你喜欢
  • 2011-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 1970-01-01
相关资源
最近更新 更多