Лучшая практика PHP MVC - передача переменной Session в класс модели из контроллера или доступ напрямую в модели - PullRequest
14 голосов
/ 21 декабря 2010

Наша команда разработчиков обсуждает лучшую практику: Лучше получить доступ к переменной сеанса непосредственно из функции в классе модели или передать переменную сеанса из контроллера в качестве аргумента функции в классе модели. Посмотрите на два примера ниже:

Доступ к переменной сеанса непосредственно из класса модели для использования в запросе:

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 ]

14 голосов
/ 21 декабря 2010

Вторая версия (передавая $ _SESSION ['userId'] в качестве аргумента методу) приводит к более разделенному классу и, следовательно, более гибкому.Иди с этим.

6 голосов
/ 21 декабря 2010

Вы НИКОГДА не хотите иметь переменные сеанса в вашей модели.Вы всегда должны передавать эти переменные в качестве параметров функции в модели.Это также делает ваш код более расширяемым и гибким.Рассмотрим модель, которая получает пользователя по его идентификатору.Вы можете написать такую ​​функцию, как:

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

Тем не менее, что если вам сейчас нужно создать функциональность администратора с функцией поиска пользователя?Ваша модель жестко запрограммирована на использование user_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;
  }

}

Это действительно базовый пример одноэлементного класса, в котором пропущено множество вещей.Если вы хотите узнать больше о синглтон-классах, задайте другой вопрос.

1 голос
/ 21 декабря 2010

Имейте в виду, что "сессия" - это просто еще одна модель. Однако первый подход недопустим - что если вы хотите получить предпочтения других пользователей, просто чтобы сравнить их с чем-то? Используйте второй подход.

0 голосов
/ 21 декабря 2010

Я согласен с Сетом.«Вам также следует рассмотреть возможность использования класса singelton для пользователя для ограничения загрузки базы данных. Создайте неизменяемый класс экземпляра с именем CurrentUser».

В моем приложении псевдо-MVC у меня есть класс User (имеется в виду текущий пользователь) сметоды сеанса, получения информации о пользователе, ролях и т. д., а также член класса (имеется в виду любого данного пользователя) с методами регистрации новых пользователей, получения / обновления их свойств и т. д., но, к примеру, не имеют ничего общего с сессиями.Кроме того, это одноэтапный сценарий, поэтому текущий пользователь статичен и не требует большого взаимодействия с БД.

Так что в моем случае мой контроллер и представления выполняют вызовы пользовательских методов, например

User::getId() или User::getGroups().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...