【问题标题】:Best way to send data from controller to view after a form is submitted?提交表单后从控制器发送数据以查看的最佳方式?
【发布时间】:2013-02-14 20:16:51
【问题描述】:

我正在使用 MVC 架构开发一个基本的 Web 应用程序。我正在构建自己的尝试并完全了解 MVC 架构的工作原理,因此这可以兼作学习练习。

我正在使用 Aura Router 类将我的 URL 映射到控制器和操作,以便将 mysite.com/login 之类的内容映射到 LoginController,如果我向 mysite.com/login/login 提交表单,它将映射它到 LoginController->doAction('login')。

控制器示例如下所示:

class LoginController implements iController {

    public function doAction( PDO $dbh, $action ) {

        switch( $action ) {
            case 'login':
                //login here
                $user = new User();
                $user_id = FALSE;

                if( $user_id = $user->login( $_POST['email'], $_POST['password'] ) ) {
                    //save user id to session
                }
                else {
                    $results = array( 'errors' => array( 'invalid' ) );
                    MembershipFunc::redirect( '/login', $results );
                }

                break;
            case 'logout':
                //logout
                break;
            default:
                break;
        }

    }
}

我面临的问题是,如果登录失败,为了避免人们刷新页面并重新提交数据,我希望将用户转发回登录页面。目前,如果我不转发它们,它们就会出现在 mysite.com/login/login 页面上,我认为它不是特别干净。我的简单登录表单没问题,因为错误可能会重定向到 mysite.com/login?error=email,password&email=user@domain.com 但是如果表单很大,那么我会得到一个巨大的 URL 查询,这真的很恶心.

我已经用基本(但有用的)PHP 代码示例搜索了关于 MVC 工作原理的良好资源,并且我一直在努力寻找特别有用的东西。我应该避免将我的 URL 结构映射到操作,而是选择放置一个名为“操作”的 POST 字段吗?我应该以某种方式构建一个系统,通过 SESSION 数据中的数组传递这些数据吗?

有什么建议吗?

注意:我只想说明我知道这个问题不适合 SO 文化,因为它可能没有正确/错误的答案,但我发现 SO 总是拥有最好/最博学的用户-根据。如果有人对我应该在哪里提出这些问题有提示,我将非常感激,所以我不会添加混乱!

【问题讨论】:

  • 为什么你的控制器知道数据库连接?为什么它只有一种方法? iController 的版权归苹果所有吗?
  • 如果你的方法中有一个switch,你需要几个方法。
  • 我会联系我的专利代理人以确保:-P。糟糕,我无法在这些 cmets 中添加新行。我只是将数据库连接向下传递,因此在访问模型时不必创建新连接。我在我的 index.php/bootloader 文件中创建了数据库,然后将它传递给控制器​​,控制器不断地向下流。
  • 我很感激人们对问题投赞成票/投反对票,但对于投反对票的人,如果你至少让我知道我可以从哪里获得关于这些类型问题的建议,我将不胜感激。我一个人工作,所以我没有被我所在领域的同行包围,所以我转向 SO。
  • 请在 youtube 上查找“干净的代码讨论”,然后阅读 M.Folwer 关于 MVC 和一般设计模式主题的内容。

标签: php model-view-controller


【解决方案1】:

在我的 MVC URL 中看起来像: index.php?c=Controller&m=ControllerMethod&d=slash/sepparated/list/of/stuff

数据 (d=) 在斜杠上展开并作为数组传递给每个控制器方法。 自动加载(通过 spl_autoload_register())用于调用类 (c=),然后调用该类中的方法 (m=)。

另外,听起来您要么没有在表单上设置 ACTION,要么故意将 ACTION 设置为 GET。作为一般规则,ACTION 应该是 POST 以保持 URL 正常。搜索表单除外。这些可以是具有各种优势的 GET。

重定向以防止在刷新时重新提交表单是您的最佳选择(可能是唯一的选择)。但在我的 MVC 中 index.php?c=user&m=login 处理登录页面和登录操作。

示例

class login extends Controller {

    public function login($data) {

        if(empty($_POST)) {

            $this->view = "login.tpl";

            return TRUE;

        }


        $res = $this->model->auth();

        if($res !== TRUE) {

            $_POST = NULL;

            $this->errorState = 1;
            $this->errorMsg = "Invalid login details";

            $this->login();

            return FALSE;

        }

        Core::setMessage('success', 'user', 'login', '2', 'Logged in successfully');

        $home = new home(); //whatever the main controller is
        $home->index($data);

        //alternatively you can redirect

        header("Location: index.php?c=home&m=index);

        return TRUE;

    }

}

这有意义还是我完全错过了标记?

【讨论】:

  • 所以你会建议通过我的表单中的隐藏字段来设置操作。现在,如果您重定向用户并丢失帖子数据,您的 Core::setMessage() 函数如何将信息发送到您的视图?
  • 我的 MVC 框架不是为处理这种情况而设计的。如果我有或想要将全局 $PAGE 变量存储在 $_SESSION 或 $_COOKIE 或其他东西(可能是 $_SESSION)中,并在页面登陆时使用它。在我的设置中,我们将 Smarty 用于模板引擎,将 Pines Notify 用于消息/错误。我们只为 smarty 分配了两个变量,$PAGE 作为 PAGE 和 $this->view 作为 TPL,它加载内部模板和所有由 Core:setMessage(); 设置的消息;以及来自 $this->errorState 和 $this->errorMessage 的那个都存储在 $PAGE['messages'] 中。
  • 我们也不设置成功登录的消息。当您看到着陆页时,很明显它是成功的。
  • 我不能“到处评论”,所以我把它放在这里:使用全局数据库处理程序。即全局$db;然后你可以通过在任何你希望它有作用域的地方重新声明全局 $db 并使用它来在任何地方使用它。
猜你喜欢
  • 1970-01-01
  • 2019-03-18
  • 1970-01-01
  • 2018-10-03
  • 1970-01-01
  • 1970-01-01
  • 2020-10-31
  • 2017-10-28
  • 2016-03-26
相关资源
最近更新 更多