@adrenalinruslan

Класс для работы с определенной таблицой?

Я пишу класс для работы с определенной таблицой, но что-то мне кажется, что я его как то неправильно пишу что-ли, быдло код) Есть ли примеры как правильно писать такой класс? К примеру, я не могу представить как сделать получение нескольких записей + к каждой этой записи добавить метод save. Например, чтобы при прохождении через цикл я мог подправить значение и вызвать save.

Как сейчас выглядит код:

class Account {
        private $database;

        private $properties = [];
        private $updated = [];

        public function __construct($database) {
            $this->database = $database;
        }

        public function __get($name) {
            if(isset($this->properties[$name])) {
                return $this->properties[$name];
            }
        }

        public function __set($name, $message) {
            if(isset($this->properties[$name])) {
                if((string) $name != 'id') {
                    $this->updated[$name] = $message;
                    $this->properties[$name] = $message;
                }
            }
        }

        public function getById($id) {
            $object = $this->database->query('SELECT * FROM `ACCOUNTS` WHERE `id` = ?', [ $id ])->fetch();

            if(isset($object->id)) {
                $this->properties = json_decode(json_encode($object), true);
            }
        }

        public function save() {
            if(isset($this->properties['id'])) {
                if(!empty($this->updated)) {
                    $prepare  = 'UPDATE `ACCOUNTS` SET ';
                    $prepare .= '`' . implode('` = ?, `', array_keys($this->updated)) . '` = ? ';
                    $prepare .= 'WHERE `id` = ?';
    
                    $this->updated += [ 'id' => $this->properties['id'] ];
                    $this->database->query($prepare, array_values($this->updated));
                    $this->updated = [];
                }
            }
        }
    }


$account = new Account($database);
    $account->getById(1);
    $account->username = '@tests';
    $account->save();
  • Вопрос задан
  • 62 просмотра
Пригласить эксперта
Ответы на вопрос 2
@sidni
Php Developer
То что вы пытаетесь реализовать, является паттерном ActiveRecord гуглите реализации.
А нюансы
  • почему класс называется Account и при этом вы используете магические гет и сет тут в принципе все ясно и вы знаете какие поля вам нужно сететить поэтому можно их просто объявить паблик полями
  • метод сохранения довольно странный как вы будете различать апдейт от инсерта (можно сделать флаг isInsert) и если модель получили через ваши методы поиска то выставить его false что означает апдейт
  • Для поиска сделайте свои методы статическими, и всегда возвращайте новый экзепляр (коллецию, массив) своего класса, тогда вы решите проблему с циклом
  • По современным правилам проектирования данный паттерн является антипаттерном тк берет на себя слишком много функциональности и привязан к конкретной бд

Хорошие реализации этого паттерна смотрите фреймверки Yii2 и Laravel
Ответ написан
Комментировать
php666
@php666
PHP-макака
Вместо
public function getById($id) {
            $object = $this->database->query('SELECT * FROM `ACCOUNTS` WHERE `id` = ?', [ $id ])->fetch();

            if(isset($object->id)) {
                $this->properties = json_decode(json_encode($object), true);
            }
        }

должно быть так (нотация твой обертки для БД не знаю, пишу наугад):
public function getById($id) {
            $object = $this->database->query('SELECT * FROM ? WHERE `id` = ?', [ $this->table, $id ])->fetch();

            if(isset($object->id)) {
                $this->properties = json_decode(json_encode($object), true);
            }
        }

т.е. если ты делаешь класс аля ActiveRecord, то уж сделай наследование от базового класса, в котором будут все методы высшего уровня типа getById (и не get, а findById). А конкретные классы должны просто от него наследоваться и иметь знания о $this->table - либо определять для каждого конкретного класса их вручную, либо с помощью какой-то магии.

В целом, всё не плохо и правильно, ты даже ввел свойство updated, за это отдельный респект.

Только я не понял этого:

if(isset($object->id)) {
                $this->properties = json_decode(json_encode($object), true);
            }


я не могу представить как сделать получение нескольких записей + к каждой этой записи добавить метод save
метод findCollectionById, к примеру. Возвращает тебе массив объектов. Проходишься циклом по этому массиву и для каждого объекта вызываешь save()
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы