【问题标题】:PHP: MVC User authentication and global user object?PHP:MVC 用户身份验证和全局用户对象?
【发布时间】:2012-11-29 12:51:26
【问题描述】:

我正在用 PHP 编写我的第一个真正的 MVC 应用程序。我没有使用框架,因为我的应用程序太小了,我认为从头开始编写所有内容会更快。

在我的应用中,用户可以注册、登录,然后编写/编辑/删除内容。每条内容都通过数据库中的用户 ID 列引用其所有者。

我现在即将实施用户访问限制(从某种意义上说,用户只能查看/编辑/删除他们的 OWN 内容/项目/模型)。我想知道应该在哪里检查“有效访问”以及在哪里实例化用户对象。

我的意思是,我肯定需要有关控制器、模型和视图中当前用户的信息。所以我在考虑是否有一个全局用户对象(在 index.php 中定义)来存储所有用户信息,以便我可以从应用程序的每个部分轻松访问它。

目前,这个 sn-p 授予我的控制器访问用户信息的权限,然后我还将这些信息存储在传递给视图的数据数组中:

class Controller {
    protected $data, $id, $user;
    public function __construct($action = null, $data = null) {
        if (User::isLoggedIn()) {
            $this->user = new User($_SESSION['user']);
            $this->data['user'] = $this->user;
        }
    }
}

按照这种模式,我必须将用户信息传递给我创建的每个模型,或者让它们实例化自己的用户对象。

去这里的路是什么?全局用户对象,在每个模型中实例化还是将用户对象作为参数传递给模型和视图?

感谢您的帮助!

【问题讨论】:

  • 关于 ACL 你可能会觉得这篇文章很有趣:stackoverflow.com/questions/3430181/acl-implementation/…
  • 嘿 PeeHaa!感谢您的链接。尽管我不想变得那么复杂,但这绝对是一本有趣的书。现在我知道“ACL”是我正在寻找的术语。也许我要做的是构建一个 ACL 类而不使用全局用户对象(但在模型和控制器中以及在需要时实例化它)。我仍然不太确定我的模型是否需要访问 ACL,或者我是否可以从我的控制器管理所有用户访问。
  • 全局Dependency Injection。紧密耦合的代码可能更容易编写,但更难维护。松散耦合的代码更难编写和概念化,但从长远来看会更容易使用。 (如果你能说出我刚刚想出的史前互联网模因,那就加分。)
  • 嘿查尔斯!感谢您的评论。我同意。我很确定您的评论旨在考虑全局用户对象。我绝对不会那样做。但是我仍然不太确定我的模型是否需要访问 ACL,或者我是否可以从我的控制器管理所有用户访问。

标签: php model-view-controller authentication


【解决方案1】:

这里有几点需要注意。首先:“然后我还将存储在传递给视图的数据数组中:”

在 MVC 中,视图可以直接访问模型,请在此处查看我的回答 How is MVC supposed to work in CodeIgniter 以了解其概述。

其次,您的问题实际上是关于依赖管理的。全局变量(以及扩展的静态变量)是有问题的(Make all variables global, PHPAre global variables bad?Static methods or not?)。首选方法是将完全构造的 $user 对象传递给需要它的类。

class Controller {
    protected $data, $id, $user;
    public function __construct(User $user) {
        if ($user->isLoggedIn()) {
    //...
       }
    }
}

但是,在这种情况下,您不能拥有完全构造的用户对象,因为您需要在构造对象之前知道用户是否登录,因此将映射器、工厂或 DAO 对象传递给构造函数并创建用户根据需要。

class Controller {
    protected $data, $id, $user;
    public function __construct(DataMapper $userMapper) {
        if (isset($_SESSION['user'])) {
    $user = $userMapper->find($_SESSION['user']);
       }
    }
}

然而,最后,如果你接受我的第一点,Views 可以直接访问他们的模型,而不是从他们的控制器获取传递的数据,那么你的控制器可能甚至不需要知道用户是否登录。这是,毕竟领域逻辑是属于模型的。

【讨论】:

  • 嗨,汤姆!非常感谢您写得很好的回复。关于“MVC vs. PAC”问题:我的视图确实直接访问模型,它们只是由控制器“加载”到数组中。因此,如果用户想要编辑链接,则控制器会加载相应的视图并将其传递给链接模型数组。这算作MVC吗?关于依赖管理:我应该尽可能避免使用全局变量等是有道理的。但是,我真的不明白您的第二个代码示例与我自己的代码示例有何不同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多