Помогите советом

DarksLight2

Знаток
⚖️
📜
Сообщения
402
Реакции
117
Здравствуйте форумчани. Посмотрите на мою какаху, и скажите как вам такой подход для работы с базой данных. Сделал аля ActiveRecords, насколько я понял, то что я написал им и является. Если нет, направьте на путь истенный. И посмотрите можно ли всё это сделать как-то иначе.

PHP:
<?php

namespace app\libs;

class ActiveRecords
{
    private $where = null;
    private $query;
    private $insert_id;
    private $query_values;

    public function __construct()
    {
    }

    private function get_table_name()
    {
        return mb_strtolower(explode('\\', get_class($this))[2]);
    }

    private function format_values($values = [], $value = false, $equality = false)
    {
        if(empty($values)) {
            return false;
        }

        $return = '';

        if($value === false) {
            foreach ($values as $field) {
                if($equality === true) {
                    $return .= '`'.$field.'` = ?,';
                } else {
                    $return .= '`'.$field.'` ,';
                }
            }
        } else {
            foreach ($values as $field => $value) {
                if($equality === true) {
                    $return .= '`'.$field.'` = ?,';
                } else {
                    $return .= '`'.$field.'` ,';
                }
                $this->query_values[] = $value;
            }
        }

        return substr($return, 0, -2);
    }

    public function select($fields = [])
    {
        if(empty($fields)) {
            $query_fields = '*';
        } else {
            $query_fields = $this->format_values($fields);
        }

        if(empty($this->query)) {
            $this->query = 'SELECT '.$query_fields.' FROM `'.$this->get_table_name().'`';
        } else {
            return null;
        }

        return $this;
    }

    public function insert($values = [], $return_id = false)
    {
        if(empty($values)) {
            return null;
        }

        $query_fields = $this->format_values($values, true);
        $query_values = '';

        for ($i = 0; $i < count($this->query_values);$i++) {
            $query_values = '?, ';
        }

        $query_values = substr($query_values, 0, -2);

        if(empty($this->query)) {
            $this->query = 'INSERT INTO `'.$this->get_table_name().'` ('.$query_fields.') VALUES ('.$query_values.')';
        } else {
            return null;
        }

        $this->insert_id = $return_id;

        return $this;
    }

    public function del()
    {
        if(empty($this->query)) {
            $this->query = 'DELETE FROM `'.$this->get_table_name().'`';
        } else {
            return null;
        }

        return $this;
    }

    public function update($values = [])
    {
        if(empty($values)) {
            return null;
        }

        $query_fields = $this->format_values($values, true, true);

        if(empty($this->query)) {
            $this->query = 'UPDATE `'.$this->get_table_name().'` SET '.$query_fields;
        } else {
            return null;
        }

        return $this;
    }

    public function truncate()
    {

        return $this;
    }

    public function where($values = [], $type = 'AND', $sign = '=')
    {
        if(isset($this->query)) {
            if( ! empty($values)) {

                $query_fields = '';

                foreach ($values as $field => $value) {
                    if($this->where === null) {
                        $query_fields .= '`' . $field . '` ' . $sign . ' ? ' . $type.' ';
                    } else {
                        $query_fields .= '`' . $field . '` ' . $sign . ' ? ' . $type.' ';
                    }
                    $this->query_values[] = $value;
                }

                if($this->where === null) {
                    $this->query .= ' WHERE '.$query_fields;
                    $this->where = 1;
                } else {
                    $this->query .= $query_fields;
                }
            }
        }

        return $this;
    }

    public function orderBY()
    {

        return $this;
    }

    public function limit()
    {

        return $this;
    }

    public function execute()
    {
        $this->query = substr($this->query, 0, -4);

        echo $this->query;
        dump($this->query_values);
    }
}
 

fulugan

Некто
📜
Сообщения
12
Реакции
2
написать велосипед принципиально? проще же готовую либу подключить, тот же RedBeanPHP
что касается кода.. я так и не понял, как это должно работать по замыслу автора, но могу смело предположить, что не будет..
теперь по поводу сути паттерна Active record: есть некоторые требования, описывающие данный паттерн:
- класс представляет собой отображение таблицы из БД;
- каждый экземпляр класса представляет собой строку в отображаемой таблице;
- код взаимодействует с отображаемой таблицей исключительно через реализованный класс.
в вашем случае проблема в отсутствии понимания сути паттерна Active record, да и в целом ООП. Почитайте теорию ооп, изучите паттерны программирования, применяемые в ооп
П.С. на истину в последней инстанции ни в коем случае не претендую))
 

DarksLight2

Знаток
⚖️
📜
Сообщения
402
Реакции
117
По замыслу использование будет такого типа
PHP:
$Users = new Users();
$Users->select()
                ->where(['id' => 0, 'name' => 'test'], 'AND', '=')
                ->execute();
в методе execute() отсылаем запрос в базу через prepared statments
Поверьте это работает, уже проверено. Зачем писать велосипед? Для обучения. Откуда такая увереннось в отсутсвии понимания ООП? Что выдаёт это?
 

fulugan

Некто
📜
Сообщения
12
Реакции
2
поясните, как у вас реализована связь между $Users = new Users() и классом ActiveRecords, и где, собственно, код класса Users?
 

DarksLight2

Знаток
⚖️
📜
Сообщения
402
Реакции
117
PHP:
<?php

namespace app\models;

use app\Models;

class Users extends Models
{
    private $session_name;

    public function __construct()
    {
        parent::__construct();
        $this->session_name = $_SERVER['HTTP_USER_AGENT'].$_SERVER['REMOTE_ADDR'];
    }

    public function check_auth()
    {
        if( $this->cookies->exists($this->session_name) === true ||
            $this->session->exists($this->session_name) === true) {

            return true;
        }

        return false;
    }
}

PHP:
<?php

namespace app;

use app\libs\ActiveRecords;
use app\libs\Cookie;
use app\libs\Session;

class Models extends ActiveRecords
{
    protected $session;
    protected $cookies;

    public function __construct()
    {
        parent::__construct();

        $this->session = new Session();
        $this->cookies = new Cookie();
    }
}
 

fulugan

Некто
📜
Сообщения
12
Реакции
2
а вот теперь про понимание ооп и, в частности, mvc и Active record..
объект Users при создании УЖЕ должен содержать необходимую информацию из бд, а не пытаться получить ее с помощью методов вручную) - у вас же создается все тот же экземпляр active records, только с именем Users, к которому вы сессию и куки прикрутили - ради чего мы все это дважды наследуем?)
зачем писать parent::__construct(); , если он пуст?
 

DarksLight2

Знаток
⚖️
📜
Сообщения
402
Реакции
117
Дело в том, что класс Users еще очень сырой. Для того чтобы в нем была информация нужно ее взять, я только сделал класс ActiveRecords для того чтобы работать с базой.
Вы имеете ввиду при создании объекта Users через __construct выбрать необходимые данные?
 

fulugan

Некто
📜
Сообщения
12
Реакции
2
Дело в том, что класс Users еще очень сырой. Для того чтобы в нем была информация нужно ее взять, я только сделал класс ActiveRecords для того чтобы работать с базой.
Вы имеете ввиду при создании объекта Users через __construct выбрать необходимые данные?
да, с использованием Active records. пример:
у вас есть модель человек, у человека есть свойства: имя, фамилия, возраст
при создании объекта (это уже конкретный человек!) вы ему задаете свойства, перечисленные в базовой модели (получаете их их бд через ваш класс Active record)
Т.е. после new Users у вас должен получиться Вася Иванов, 25 лет. а не "неизвестный человек"
 

Bayer

Специалист
⚖️
🏆
📜
Сообщения
720
Реакции
246
Посмотри в сторону DataMapper
 

DarksLight2

Знаток
⚖️
📜
Сообщения
402
Реакции
117
Переписал

PHP:
<?php

namespace app\models;

use app\libs\ActiveRecords;

class Users extends ActiveRecords
{
    public function __construct($data = [])
    {
        if(isset($data)) {
            foreach ($this->select()->where($data)->execute() as $field => $value) {
                $this->$field = $value;
                return $this;
            }
            return null;
        }
    }
}

Теперь работает так как вы писали, но, я сделал иначе, вместо айдишника поиск пользователя в базе можно указывать через массив.
Пример:
PHP:
$this->user_data = new Users([
    'session_name'  => $this->session_name,
    'session_value' => $this->cookies->get($this->session_name)
                             ]);
 

Bayer

Специалист
⚖️
🏆
📜
Сообщения
720
Реакции
246
Переписал

PHP:
<?php

namespace app\models;

use app\libs\ActiveRecords;

class Users extends ActiveRecords
{
    public function __construct($data = [])
    {
        if(isset($data)) {
            foreach ($this->select()->where($data)->execute() as $field => $value) {
                $this->$field = $value;
                return $this;
            }
            return null;
        }
    }
}

Теперь работает так как вы писали, но, я сделал иначе, вместо айдишника поиск пользователя в базе можно указывать через массив.
Пример:
PHP:
$this->user_data = new Users([
    'session_name'  => $this->session_name,
    'session_value' => $this->cookies->get($this->session_name)
                             ]);
С куками есть проблемы в безопасности.
К примеру подмена.
 

Bayer

Специалист
⚖️
🏆
📜
Сообщения
720
Реакции
246
Как сделать безопаснее?
Ну если выбирать между сессиями и куками, то сессии, однако у них минус в том что они хранятся 15 мин, поэтому для авторизаций и популярны куки. Но как я понял у тебя иная задача тебе нужно идентифицировать пользователя, а для этого можно использовать любые идентификаторы
 

DarksLight2

Знаток
⚖️
📜
Сообщения
402
Реакции
117
Можно ведь делать авторизацию и с куками и с сессией, чтобы сверять данные, если сессия хранится 15 мин, то можно каждые 15 мин делать новый хэш и все. Как идейка?
 

Insallah

¯\_(ツ)_/¯
🏆
📜
Сообщения
1,471
Реакции
451
По замыслу использование будет такого типа
PHP:
$Users = new Users();
$Users->select()
                ->where(['id' => 0, 'name' => 'test'], 'AND', '=')
                ->execute();
в методе execute() отсылаем запрос в базу через prepared statments
Поверьте это работает, уже проверено. Зачем писать велосипед? Для обучения. Откуда такая увереннось в отсутсвии понимания ООП? Что выдаёт это?

Я тут пробегаю мимо с классическим вопросом: "нахрена?". Это же хоронит читабельность запросов и при этом не сильно укорачивает или модулирует систему.
Заход через подготовленные выражения оставляет запрос читабельным и не отбирает возможностей. Что-то типа query('SELECT * FROM accounts WHERE username = ? AND password = ?', 'test', 'test').
 

Bayer

Специалист
⚖️
🏆
📜
Сообщения
720
Реакции
246
Можно ведь делать авторизацию и с куками и с сессией, чтобы сверять данные, если сессия хранится 15 мин, то можно каждые 15 мин делать новый хэш и все. Как идейка?
Очередной велосипед, причём нагружаемый
Чем
Код:
new Users($id);
не устроило? :rolleyes:
 
Последнее редактирование:

DarksLight2

Знаток
⚖️
📜
Сообщения
402
Реакции
117
Но мне нужно узнать авторизирован ли пользователь
 
Сверху