4
4
4sadly2020-05-15 20:45:15
PHP
4sadly, 2020-05-15 20:45:15

Are the classes implemented correctly?

ActiveRecord class

abstract class ActiveRecord
{
    protected int $id;
    protected static $db;

    public static function setup($type, $user, $pass, $opt)
    {
        self::$db = new \PDO($type, $user, $pass, $opt);
    }

    abstract protected static function getTableName(): string;

    public static function findAll(): ?array
    {
        $stmt = self::$db->prepare('SELECT * FROM ' . static::getTableName());
        $stmt->execute();
        $r = $stmt->fetchAll();
        $c = sizeof($r);
        for ($i = 0; $i < $c; $i++) {
            $r[$i] = new static($r[$i]);
        }
        return $r ? $r : null;
    }

    public static function findById(int $id): ?object
    {
        $stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE id = ?');
        $stmt->execute([$id]);
        $r = $stmt->fetch();

        return $r ? new static($r) : null;
    }

    public static function findByAttribute(array $attributes): ?object
    {
        $keys = array_keys($attributes);
        foreach ($keys as $key => $value) {
            $keys[$key] = '`' . $value . '` = ?';
        }
        $stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . implode(' AND ', $keys));
        $stmt->execute(array_values($attributes));
        $r = $stmt->fetch();
        return $r ? new static($r) : null;
    }

    public static function findCollectionByAttribute(array $attributes): ?array
    {
        $keys = array_keys($attributes);
        foreach ($keys as $key => $value) {
            $keys[$key] = '`' . $value . '` = ?';
        }
        $stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . implode(' AND ', $keys));
        $stmt->execute(array_values($attributes));
        $r = $stmt->fetchAll();
        $c = sizeof($r);
        if ($c > 0) {
            for ($i = 0; $i < $c; $i++) {
                $r[$i] = new static($r[$i]);
            }
            return $r;
        }
        return null;
    }

    public static function whereOne($query, array $attributes): ?object
    {
        $stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . $query);
        $stmt->execute([$attributes]);
        $r = $stmt->fetch();
        return $r ? new static($r) : null;
    }

    public static function whereCollection($query, array $attributes): ?array
    {
        $stmt = self::$db->prepare('SELECT * FROM `' . static::getTableName() . '` WHERE ' . $query);
        $stmt->execute([$attributes]);
        $r = $stmt->fetchAll();
        $c = sizeof($r);
        if ($c > 0) {
            for ($i = 0; $i < $c; $i++) {
                $r[$i] = new static($r[$i]);
            }
            return $r;
        }
        return null;
    }

    public static function deleteById(int $id): void
    {
        self::$db->prepare('DELETE FROM `' . static::getTableName() . '` WHERE id = ?')->execute([$id]);
    }

    public function save(): void
    {
        $properties = get_object_vars($this);
        if (empty($properties['id'])) {
            $questionmarks = array_fill(0, sizeof($properties), '?');
            $stmt = self::$db->prepare('INSERT INTO `' . static::getTableName() . '` (`' . implode('`,`', array_keys($properties)) . '`) VALUES (' . implode(',', $questionmarks) . ')');
            $stmt->execute(array_values($properties));
            $this->id = self::$db->lastInsertId();
        } else {
            $keys = array_keys($properties);
            foreach ($keys as $key => $value) {
                $keys[$key] = $value . ' = ?';
            }
            $stmt = self::$db->prepare('UPDATE `' . static::getTableName() . '` SET ' . implode(',', $keys) . ' WHERE id = ?');
            $stmt->execute(array_merge(array_values($properties), [$this->id]));
        }
    }

    public function delete(): void
    {
        self::$db->prepare('DELETE FROM `' . static::getTableName() . '` WHERE id = ?')->execute([$this->id]);
    }

    public function getId(): int
    {
        return $this->id;
    }

}

User class:
class User extends ActiveRecord
{
    protected string $login;
    protected string $password;
    protected string $fullname;
    protected string $type;
    protected int $status;

    protected static function getTableName(): string
    {
        return 'users';
    }

    /**
     * @return string
     */
    public function getLogin(): string
    {
        return $this->login;
    }

    /**
     * @param string $login
     */
    public function setLogin(string $login): void
    {
        $this->login = $login;
    }

    /**
     * @param string $password
     */
    public function setPassword(string $password): void
    {
        $this->password = $password;
    }

    /**
     * @return string
     */
    public function getFullname(): string
    {
        return $this->fullname;
    }

    /**
     * @param string $fullname
     */
    public function setFullname(string $fullname): void
    {
        $this->fullname = $fullname;
    }

    /**
     * @return string
     */
    public function getType(): string
    {
        return $this->type;
    }

    /**
     * @param string
     */
    public function setType(string $type): void
    {
        $this->type = $type;
    }

    /**
     * @return int $status
     */
    public function getStatus()
    {
        return $this->status;
    }

    /**
     * @param int $status
     */
    public function setStatus($status): void
    {
        $this->status = $status;
    }

    public function isFree(): bool
    {
        if ($this->status < 2) return true;
        return false;
    }

    public function validatePassword($password): bool
    {
        return password_verify($password, $this->password);
    }

Something tells me that you can make an array of data, create an ActiveRecord __construct and use it in child classes, or should it be done differently? if you can - give advice, I will be grateful
It is useless to write about me not creating bicycles

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Maxim, 2020-05-15
@4sadly

If you don't want to use a ready-made one, you can create your own. There is nothing wrong with that. Most often, ready-made has dependencies and this is not always suitable. Your model resembles the yii2 model. I think it will be useful for you to take a look at Yii2's Active Record base and main class. Hope you didn't see it.
According to the current comments, AR has public properties for simplicity and rapid development and they are equal directly in the database, which allows you to get rid of getters and setters, they act as public properties, like a kind of DTO. So the properties themselves are not logical for you that they have non-public access.

P
Pavel Omelchenko, 2020-05-16
@pOmelchenko

public function isFree(): bool
    {
        if ($this->status < 2) return true;
        return false;
    }

Why couldn't it just be done ? return $this->status < 2

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question