Там в соседнем треде
FanatPHP всё правильно написал, что для понимания почему так не надо делать - нужен опыт.
Но если постараться очень кратко и без введения "лишних классов", то всё же, думаю, это всё дело чуть-чуть можно улучшить:
1) За хранилище юзеров должно отвечать хранилище юзеров
2) За юзера должен отвечать юзер
3) За соединение к бд - соединение к бд
Ваш капитан очевидность)
Тут кажется понятно? Тогда сделаем:
// Соединение к БД
$connection = new PDO(...);
// Хранилище с одним "findById"
class UsersDatabaseRepository
{
public function __construct(PDO $connection) { ... }
public function findById(int $id): ?User
{
$stmt = $this->prepare('SELECT * FROM `users` WHERE id = ? LIMIT 1');
$stmt->execute([$id]);
return new User($stmt->fetch(PDO::FETCH_ASSOC)) ?: null;
}
public function save(User $user): void
{
// ...
}
}
// Юзер с одним полем "id"
class User
{
public int $id;
public function __construct(array $attributes)
{
$this->id = $attributes['id'] ?? 0;
}
}
// В качестве бонуса: Теперь у нас один и тот же юзер может храниться где угодно!
// А сам User мы вообще не трогали - просто добавили новый класс, который хранит всё в файликах
class UsersFilesystemRepository
{
public function findById(int $id): ?User { /* какой-то код */ }
}
// В качестве бонуса N2: А ещё мы точно так же можем получать этого
// юзера через API с какого-нибудь GitHub
class UsersGithubRepository { ... }
В "большом мире" всё чуть посложнее. Например:
1) Передавать массив в конструктор User - это не очень.
2) findById переусложнён, и его можно вполне упростить, вынеся подобный "похожий" код на уровень выше в AbstractDatabaseRespotory
3) Работать с репой (хранилищем) стоит через интерфейс (точнее через их набор), а не через реализацию.
Ну и так далее...
В любом случае хотя бы такое разделение позволит тебе проще организовать код.