【问题标题】:Processing form data in MVC/OOP structure在 MVC/OOP 结构中处理表单数据
【发布时间】:2012-09-22 09:46:14
【问题描述】:

我已经创建了一个登录系统,我正在尝试尽可能地遵守 MVC 的规则。

我有一个简单的登录表单,它使用 AJAX 将表单数据提交给小脚本,然后调用控制器处理用户名和密码:

function __autoload($classname) {
    include("../classes/$classname.php");
}

$username = $_POST['username'] ;
$password = $_POST['password'] ;

$AC = new AccessControl ;

$result = $AC->login($username, $password) ;

if($result !== 0)
{
echo $result ;
exit() ;
}

AccessControl 是我的用户认证和账户管理操作类,代码在我的另一篇文章中:MVC Relationships and DRY

我做错了吗,因为这个小脚本不是控制器或模型?它所做的只是将控制器返回的信息中继回接口/视图,例如错误消息。

【问题讨论】:

    标签: php oop model-view-controller


    【解决方案1】:

    首先,不要让任何特定的范式妨碍您以最佳方式在您的特定情况下

    也就是说,你的小脚本一个控制器。它正在处理一个动作并返回一个结果。它可能不是管理特定视图,而是委派处理并将结果交给视图。

    【讨论】:

      【解决方案2】:

      在我看来,没有使用MVC structre到血液中,这个是正确的,有一些小的变化。

      我通常喜欢这样的东西:

      $AC = new AccessControl ;
      $AC->setUsername($_POST['username']);
      $AC->setPassword($_POST['password']);
      if ( $AC->login() )
           echo $result // if all is ok from login method return true
      else
           // manage some error handling here if not true
      

      也许您想在更多地方和其他方法中使用该用户名和密码,因此您可以使用getPassword() / getUsername()

      【讨论】:

        【解决方案3】:

        您正在混合身份验证和授权。像AccessControl 这样的结构应该处理授权,而不是身份验证.. 您选择的名称.. emm ... 留有改进的空间。要了解更多关于 MVC 上下文中的授权,我建议阅读this post

        在 MVC 和受 MVC 启发的设计模式的上下文中,身份验证应该是模型层的一部分,并由某种形式的识别服务处理。


        您在代码剪辑器上的内容看起来像控制器方法中的机器人代码,但它有几个问题。

        好的 .. 让 pike 分开编码:

        • 不推荐使用__autoload()函数。相反,您应该学习如何使用spl_autoload_register() 函数。它可以让您编写代码以使用多个领导者。

          此外,从 5.3 版本开始,可以在 PHP 中使用namespaces。结合自动加载器,它可以让你更好地组织你的代码。最近,将项目目录结构(至少部分)映射到命名空间是一种常见的做法。

          最著名的实现是PSR-0,尽管它不应该被认为是接近理想的。它有一些严重的缺陷,但它将成为一个很好的例子来说明在自动加载中使用命名空间。

        • 您应该避免在应用程序调用图中使用new。这会导致与创建新实例的类的名称紧密耦合。

          相反,您的控制器应该有一个工厂注入到构造函数中,然后负责初始化新实例。

          namespace Controller;
          
          class Foo
          {
              protected $serviceFactory = null;
              protected $view = null;
          
              // --- SNIP ---
              public function __construct( HasSomeFactoryInterface $factory, $view )
              {
                  $this->serviceFactory = $factory;
                  $this->view = $view;
              }
          
              public function postLogin( $request )
              {
                  $recognition = $this->serviceFactory->create('AccessControl');
          
                  // --- SNIP ---
          
          }
          
        • MVC 设计模式中的控制器应该只改变模型层和当前视图的状态。它不返回任何内容,也不将数据从模型层传递到视图。您似乎混淆了经典 MVC、Model2 MVC、MVP、MVVP 和 MVC 模式的 Rails 模仿。

          在 Model2 MVC(也称为 Web MVC)设计模式中,控制器接收传入的用户请求,并通过将来自所述请求的数据传递到三元组的各个部分来更改它们的状态。

          namespace Controller;
          
          class Foo
          {
          
              // --- SNIP ---
              public function postLogin( $request )
              {
                  $recognition = $this->serviceFactory->create('AccessControl');
                  $recognition->login( $request->getPost( 'username' ),
                                       $request->getPost( 'password' ) );
          
                  $this->view->prepare( $request->getMethod() );
              }
              // --- SNIP ---
          
          }
          

          在此示例中,视图接收到通知,即收到了POST 请求,这意味着,它不必从多个模板生成 HTML,而只需发送 HTTP 标头作为响应。

          要查看有关 MVC 相关模式的简短概述,请尝试this post

        • 如果您的目标是 Model2 MVC 设计模式,则视图应自行从模型层检索信息。但是所有受 MVC 启发的设计模式视图都应该负责表示逻辑。

          这还包括处理模型层中的错误状态。领域业务逻辑与视图如何表示错误无关。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-01-24
          • 1970-01-01
          • 1970-01-01
          • 2014-01-01
          • 1970-01-01
          • 2012-11-24
          • 2020-05-31
          相关资源
          最近更新 更多