PHP MVC最佳实践 - 将Session变量传递给控制器​​的模型类或直接在模型中访问

时间:2010-12-21 18:35:27

标签: php model-view-controller design-patterns session

我们的开发团队正在讨论一般的最佳实践: 是直接从模型类中的函数访问会话变量还是将会话变量从控制器作为参数传递给模型类中的函数更好。请看下面的两个例子:

直接从模型类访问会话变量以在查询中使用:

class MyModel {
    public function getUserPrefs($userID) {
        $this->query("SELECT * FROM my_table WHERE id=$_SESSION['userID']");
    }
}

或者将会话变量从控制器传递给模型类中的函数作为函数参数:

class MyController {
    public function displayUsers() {
        $this->model->getUserPrefs($_SESSION['userID']);
    }
}

class MyModel {
    public function getUserPrefs($userID) {
        $this->query("SELECT * FROM my_table WHERE id=$userID");
    }
}

从控制器传递给模型的原因是所有引用的数据都来自一个入口点,即控制器。

什么被认为是更好的做法?

4 个答案:

答案 0 :(得分:14)

第二个版本(将$ _SESSION ['userId']作为方法的参数传递)会导致更多的解耦类,因此更灵活。跟着它。

答案 1 :(得分:6)

您永远不希望在模型中拥有会话变量。您应该始终将这些变量作为参数传递给模型中的函数。这也使您的代码更具扩展性和灵活性。考虑一个通过id获取用户的模型。您可以编写如下函数:

function find_by_id() {
  // SELECT * FROM Users WHERE user_id = $_SESSION['user_id'];
}

但是,如果您现在要使用用户查找功能构建管理功能,该怎么办?您的模型是硬编码的,以使用会话的user_id,但您希望能够传递自己的ID。你会更好:

function find_by_id($id) {
  // SELECT * FROM Users WHERE user_id = $id
}

并在您的控制器中

$user = Model::find_by_id(1);
//or
$user = Model::find_by_id($_SESSION['user_id']);
//etc

但是,在这种情况下,我真的会考虑使您的代码更加灵活:

function find($ids) {
  // this is pseudo code, but you get the idea
  if(is_array($ids))
    $ids = implode(',', $ids); // if an array of ids was passed, implode them with commas
  SELECT * FROM Users WHERE user_id IN ($ids);
}

这允许您在一个查询中获得多个用户!哪种方式更有效率。然后,在您看来:

foreach($users as $user){
  // iterate over each user and do stuff
}

您还应该考虑为用户使用singelton类来限制数据库负载。创建一个名为CurrentUser的不变实例类(例如):

class CurrentUser {

  private static $user;

  // we never instantiate it -its singleton
  private function __construct() {}

  public function user() {
    return self::$user;
  }

}

这是单例类的一个非常基本的例子,并且缺少很多东西。如果您想了解有关单身人士课程的更多信息,请发布另一个问题。

答案 2 :(得分:1)

请记住,“会话”只是另一种模式。然而,第一种方法是不可接受的 - 如果您想获取另一个用户首选项只是为了将它们与某些内容进行比较,该怎么办?使用第二种方法。

答案 3 :(得分:0)

我同意赛斯的观点。 “您还应该考虑为用户使用singelton类来限制数据库负载。创建一个名为CurrentUser的不变实例类。”

在我的伪MVC应用程序中,我有类User(意味着当前用户),其中包含会话方法,获取用户信息,角色等,以及类成员(意味着任何给定用户)以及注册新用户,获取/更新的方法他们的属性等,但与会话无关,例如。此外,它是一个单例场景,因此当前用户是静态的,并且不需要与DB进行太多交互。

所以在我的情况下,我的控制器和视图会调用User方法,例如

User::getId()User::getGroups()