处理MVC / OOP结构中的表单数据

时间:2012-09-17 14:03:34

标签: php oop model-view-controller

我已经创建了一个登录系统,我试图尽可能地遵守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

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

3 个答案:

答案 0 :(得分:1)

首先,不要让任何特定范例阻止您在特定情况下以最佳方式做事

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

答案 1 :(得分:0)

在我看来,没有将MVC结构用于血液,这是正确的,有一些小的改变。

我通常喜欢这样的东西:

$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()

答案 2 :(得分:0)

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

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


你在代码片段中所拥有的东西看起来像是来自控制器方法的类似机器人的代码,但它有几个问题。

好吧..让派克分开编码:

  • 不建议使用__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启发的设计模式视图都应该负责表示逻辑。

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