Я работаю над системой администратора, которая позволяет пользователям управлять своим профилем пивоваренного завода и инвентарем пива.
У меня есть три связанных таблицы: пользователи, пивоваренные заводы и пиво. Между пользователями и пивоваренными заводами существует отношение 1: 1, а между пивоваренными заводами и пивом 1: 1. Каждая таблица имеет соответствующий DAO: UserDAO, BreweryDAO и BeerDAO соответственно.
Если пользователь хочет добавить пиво, например, они будут переходить на страницу, beer.php?brewery=123
где 123
идентификатор пивоварни, к которой будет добавлено это новое пиво. Если пользователь хочет обновить пиво, он перейдет на ту же страницу, например, beer.php?id=456
, где 456
идентификатор пива, которое будет отредактировано.
Теперь, когда я захожу на страницу пива, мне нужны две части информации: пивоварня и пиво, если они редактируют. Я также должен убедиться, что пивоварня принадлежит зарегистрированному пользователю.
Я могу придумать два способа сделать это:
Опция 1: Использование множества запросов без соединений
// get relevant data for adding a new beer
if (isset($_GET['brewery'])) {
$brewery = $breweryDAO->getBreweryById($_GET['brewery']);
// check if no brewery or brewery doesn't belong to user
if (!$brewery || $brewery->user_id != $currentUser->id) {
// error
}
// get relevant data for editing a beer
} elseif (isset($_GET['id'])) {
$beer = $beerDAO->getBeerById($_GET['id']);
if ($beer) {
$brewery = $breweryDAO->getBreweryById($beer->id);
}
// check if no beer, no brewery, or brewery doesn't belong to user
if (!$beer || empty($brewery) || $brewery->user_id != $currentUser->id) {
// error
}
} else {
// error
}
Вариант 2: Использование одного запроса с JOIN
// get relevant data for adding a new beer
if (isset($_GET['brewery'])) {
// get user's brewery
$brewery = $breweryDAO->getBreweryByIdAndUser($_GET['brewery'], $currentUser->id);
// check if no brewery was found
if (!$brewery) {
// error
}
// get relevant data for editing an existing beer
} elseif (isset($_GET['id'])) {
// get user's beer AND brewery information all together
$beer = $beerDAO->getBeerByIdAndUser($_GET['id'], $currentUser->id);
// check if no beer was found
if (!$beer) {
// error
}
} else {
// error
}
При извлечении пива лучше делать отдельные запросы (Опция 1) или использовать одиночные объединенные запросы (Вариант 2) Меня беспокоит вопрос о том, какой из подходов лучше будет запрашивать множественную информацию, которая зависит друг от друга. Я обычно делаю Опция 1, но это может стать довольно грязным, чем больше отношений. Я не слишком обеспокоен скоростью. Есть ли другой способ структурировать мой код, так как оба варианта кажутся грязными?
Когда вы хотите добавить пиво, вы действительно хотите добавить что-то в пивоварню. Поэтому я бы изменил структуру приложения и создал brewery.php? Id = breweryid для редактирования пивоваренных заводов.
Это был бы возможный шаг, чтобы ваши файлы были немного меньше (нет необходимости во внешней структуре elseif {} else {}, так как вам нужно только напрямую проверить заданный идентификатор) и больше фокусировались на объектах. По крайней мере, вам не нужно проверять, действительно ли вы хотите взаимодействовать с пивом или пивоварней.
Следующим шагом будет не загружать полный объект brewery просто для сравнения идентификатора пользователя с currentUser. Вы можете просто создать такой метод, как
/**
* @param int $breweryId
* @param int $userId
* @return boolean
*/
public function breweryBelongsToUser($breweryId, $userId){
// return false if no entry in database
}
Других решений пока нет …