Ответ 1
Вторая версия (передача $_SESSION ['userId'] в качестве аргумента метода) приводит к более развязанному классу и, следовательно, более гибкой. Пойдите с ним.
Наша команда разработчиков обсуждает общую передовую практику: Лучше ли получить доступ к переменной сеанса непосредственно из функции класса модели или передать переменную сеанса из контроллера в качестве аргумента функции в классе модели. Посмотрите на два примера ниже:
Доступ к переменной сеанса непосредственно из класса модели для использования в запросе:
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");
}
}
Проводя его с моделью с контроллера, так что все данные, на которые делается ссылка, поступают из одной точки входа, которая является контроллером.
Что считается лучшей практикой?
Вторая версия (передача $_SESSION ['userId'] в качестве аргумента метода) приводит к более развязанному классу и, следовательно, более гибкой. Пойдите с ним.
Вы НИКОГДА не хотите иметь переменные сеанса в своей модели. Вы всегда должны передавать эти переменные в качестве параметров функции в модели. Это также делает ваш код более расширяемым и гибким. Рассмотрим модель, которая получает пользователя по их идентификатору. Вы можете написать такую функцию, как:
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 = $_SESSION['user_id']
}
и в вашем контроллере
$user = Model::find_by_id(1);
//or
$user = Model::find_by_id($_SESSION['user_id']);
//etc
В этом случае, однако, я действительно хотел бы сделать ваш код еще более гибким:
function find($ids) {
// this is sudo 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;
}
}
Это действительно базовый пример одноэлементного класса и отсутствует много материала. Если вы хотите узнать больше об одноэлементных классах, отправьте еще один вопрос.
Имейте в виду, что "сеанс" - это еще одна модель. Однако первый подход неприемлем - что, если вы хотите получить другие предпочтения пользователей, просто чтобы сравнить их с чем-то? Используйте второй подход.
Я согласен с Seth re. "Вы также должны рассмотреть возможность использования класса singelton для пользователя для ограничения загрузки базы данных. Создайте не меняющийся класс экземпляра под названием CurrentUser".
В моем приложении pseudo-MVC у меня есть класс User (что означает текущий пользователь) с методами для сеанса, получения информации о пользователе, ролях и т.д. и члена класса (что означает любого данного пользователя) с методами регистрации новых пользователей, получения/обновления их свойства и т.д., но не имеет ничего общего с сеансами. Кроме того, это одноэлементный сценарий, поэтому текущий пользователь статичен и не требует большого взаимодействия с БД.
Итак, в моем случае мой контроллер и представления совершают вызовы методам пользователя, например.
User::getId()
или User::getGroups()
.