@4sadly

Как реализовать доступ к бд в классе пользователя?

Хочу создать класс пользователя, но как в нем получать доступ к бд?
Будет ли нормально сделать вот так?
class User{
private static $db = '';
    
    public static function setup($type, $user, $pass, $opt)
    {
        self::$db = new PDO($type, $user, $pass, $opt);
    }
}
User::setup($type, $user, $pass, $opt);
  • Вопрос задан
  • 120 просмотров
Пригласить эксперта
Ответы на вопрос 3
FanatPHP
@FanatPHP
Чебуратор тега РНР
Будет ли нормально сделать вот так?

Конечно нормально.
Будет, к примеру, в приложении 10 разных классов - и будет 10 соединений с БД. 100 классов - 100 соединений. Что тут такого?

Как реализовать доступ к бд в классе пользователя?

По-хорошему, в классе User не должно быть никакого доступа к БД. Но до понимания этого тебе ещё лет пять.

Поэтому можешь просто подключиться с БД и передать в класс уже готовое соединение
public static function setup($pdo)
    {
        self::$db = $pdo;
    }


Но учитывая что у тебя никакой не ООП а голимая процедурщина, то можешь просто писать global $pdo в "методах" своего "класса" и не париться
Ответ написан
revenger
@revenger
49.5
Не идеально, но можно попробовать как-то так
Ответ написан
SerafimArts
@SerafimArts
Senior Notepad Reader
Там в соседнем треде 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) Работать с репой (хранилищем) стоит через интерфейс (точнее через их набор), а не через реализацию.
Ну и так далее...

В любом случае хотя бы такое разделение позволит тебе проще организовать код.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы