Честно говоря, я не уверен, что это лучшее место для такого вопроса. Возможно, codereview подходит лучше. Кроме всего прочего, ИМО, ни один из двух вариантов, которые вы предлагаете, не является "лучшим подходом". Но, как всегда, это может быть личным делом.
На мой взгляд, лучший способ реализовать ООП — это как можно скорее передать все ваши данные в объекты и реализовать сервисный уровень, который берет на себя операции, требующие нескольких запросов или нескольких объектов.
Если я могу предположить, что вы используете шаблон MVC-ish, ваш контроллер получает данные. Там вы создаете экземпляр объекта Game
и устанавливаете идентификатор 123456
. Вы можете передать этот экземпляр методу службы с именем fillGameModel(Game $gameInstance)
. Этот метод подключается к БД, устанавливает все остальные свойства объекта Game
и возвращает его. То же самое касается объекта User
. Оба этих объекта затем можно передать другому методу службы: likeGame(Game $game, User $user)
. Этот метод может позаботиться обо всем остальном.
Лично я бы пошел еще дальше и использовал преобразователи для доступа к БД, но сейчас я не буду об этом. Вот пример использования службы и более объектно-ориентированный подход:
//controller:
$user = new User();
$user->setId($_SESSION['user_id']);
$game = new Game();
$game->setId(123456);//wherever you get this from
$service = new MainService();
$service->userLikes($game,$user);
//service:
public function userLikes(Game $game, User $user)
{
$user = $this->_completeUser($user);
$game = $this->_completeGame($game);
//insert or update whatever data you need...
}
protected function _completeUser(User $user)
{
$db = $this->_getConnection();//asuming PDO, to keep things simple
$query = 'SELECT * FROM my_db.users WHERE id = ?';
$stmt = $db->prepare($query);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
foreach ($row as $field => $value)
{//this implies getters and setters in your model
$user->{'set'.ucfirst(strtolower($field))}($value);
}
return $user;
}
protected function _completeGame(Game $game)
{
$db = $this->_getConnection();
$query = 'SELECT * FROM my_db.games WHERE id = ?';
$stmt = $db->prepare($query);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
foreach ($row as $field => $value)
{//field id becomes "setId" method, field name "setName" etc...
$game->{'set'.ucfirst(strtolower($field))}($value);
}
return $game;
}
//just for show: a pseudo-overloader method, if your models all share the same
//abstract class.
protected function _completeAny(Model_Abstract $model)
{
$modelName = get_class($model);
if (method_exists($this,'_complete'.$modelName))
{
return $this->{'_complete'.$modelName}($model);
}
throw new Exception('No completion method for '.$modelName.' found');
}
Опять же, циклы по результирующему набору можно заменить методом в классе абстрактной модели, который принимает массив в качестве аргумента и преобразует имена полей в соответствующие установщики. Много места для абстракции, я бы сказал ;-)
person
Elias Van Ootegem
schedule
18.09.2012
Is it a good practice to grab current user id in Game model?
Нет.or should I pass it as parameter?
Да. Подумайте об этом, прямо сейчас вы сохраняете идентификатор своего активного пользователя в сеансе, что произойдет, если позже вы сохраните его где-то еще? Что еще более важно, ваша функция может использоваться только для текущего активного пользователя, вы не можетеlike()
для любого другого пользователя. Идентификатор пользователя является внешней зависимостью, нет абсолютно никаких причин привязывать к нему вашу игровую модель, прочтите зависимость инъекции. - person yannis   schedule 18.09.2012