Сессии до это в каком то уроке разбирались, но вскользь, пару минут уделили им все. Всем было все понятно, один я ничего не понял.
Конкретных реализаций я не понял, слишком много кода было и запутано как то все.
А потом из, например, Posts обращаемся к классу UserQueries и получаем лайкнувших, из новостей опять обращаемся к UserQueries и выбираем метод для получения тех, кто поделился и т.д. В итоге, если что-то поменяется в БД с таблице Users, мы всегда сможем внести изменения в одном файле и не париться о том, что где-то еще есть запросы? Я правильно понял? Для этого и нужно разделять логику и запросы к БД?
Извиняюсь за свою тупость... Но читаю книгу
Поэтому, когда начинаю все совмещать, вижу, что программа проходит массив несколько раз, вместо того чтобы пройти один и вывести все нужные данные - считаю, что делаю что-то не так...
а код получается разбросанным.
Значит прямо в методе GetUsersLiked() делаем запрос в БД
Получается в методе selectAllFromUsersTableEtc() мы получаем список всех пользователей?
class UserQueries {
public function getUserWithAvatar($ids = []) {
$result = $this->db
->createCommand("SELECT u.id, u.name, f.name AS avatar_name from users u inner join files f ON f.id = u.avatar_id")->execute();
//делаем кучу правильных обработок, учитываем что
//если $ids не пустой то нужно сформировать WHERE id IN ();
// возможно кешируем запрос, если он будет часто браться
return $result;
}
}
class UsersController()
{
//список всех юзеров с аватарками
public function actionIndex() {
$uq = new UserQueries();
// сырая инфа из базы!
$usersList = $uq->getUserWithAvatar();
// пути разошлись! вы можете 1) создать контейнер со всеми чисто-аватарками
//и контейнер с чисто-юзерами по отдельности
//2) создать контейнер с UsersWithAvatar - да-да, эта фиговина будет хранить модели пользователей с аватарками!
// только прочтите правильно: модели (пользователей с аватарками)
// а не модели пользователей и модели аватарок.
//"Так это же дублирование..? ведь есть Users, какой еще UsersWithAvatar??" - можете спросить вы, но я отвечу -
//светлые головы изобрели наследование для таких моментов, и UsersWithAvatar just extends UsersContainer
return new UserWithAvatarsContainer($usersList);
//или, как в фреймворках делается:
// return $this->render('index', [ 'dataProvider' => $userWithAvProvider ] );
}
}
// какая-нибудь вьюха
//($container это наш $userWithAvContainer)
$usersWithAv = $container->getAll(/*обычно это делается с пагинацией, а то от 124123242 юзеров всё умрёт*/);
for ($i = 0, $sz = count($usersWithAv); $i < $sz; $i++) :?>
<?php $current = $usersWithAv[$i]; ?>
<?= $current->first_name?>
<?php endfor;?>
И на сколько я понял по вашему ответу, нужно так и создавать методы со своими запросами к БД в одном классе Users?
т.е. класс получится примерно таким?
// получаем список лайкнувших пост
function getUsersLiked($post_id){
// запрос в БД
}
function showUsers(){
// Выводим все, что есть в массиве $this->users
// При этом проверяя существование каждого поля, если его нет - просто не выводим
}
// получаем список всех юзеров
function getAllUsers(){
// запрос к БД
}
function getAllUsers() {
$usersRecords = $this->dbConnection->selectAllFromUsersTableEtc();
for ($i = 0, $size = count($usersRecords); $i < $size; $i++ )
{
$currentRec = $usersRecords[$i];
//that's what i mean when said 'preparing', обработка
$location = [ //or $this->formateLoc($currentRec);
"city" => $currentRec["city_name"],
"country" => $currentRec["country_name"]
];
$this->addUser($currentRec['id'], $currentRec["first_name"], $currentRec["last_name"], $location, //...);
}
}
function addUser($id, $firstName, $lastName, $locObject) {
//check for values
$user = new User($id); //эх а вот был бы у вас этот класс, а не просто массив...
$user->firstName = $firstName;
$user->lastName = $lastName;
if(! isset($locObject["country"]) ) {
throw new \Exception("Location object is invalid");
}
$user->setLocation($locObject);
$this->users[$id] = $user;
}
А оно скорее всего = 0.
Поэтому в массиве ничего не находит