ActiveRecord своими руками на PHP

в 9:06, , рубрики: active record, mysql, php, Zend Framework, базы данных, ооп, шаблоны проектирования

Доброго времени суток! Я работаю над веб-проектом X. Проект большой, сложный и перспективный. Но, как и в любом другом проекте, есть много кода, написанного наспех с пометкой «когда-нибудь исправлю».

Пришло время исправлять.

Читая очередной мануал, я обнаружил шаблон проектирования «Active Record». Простой запрос в Google, и вот уже подруга Википедия коротко и ясно рассказала обо всём (https://ru.wikipedia.org/wiki/ActiveRecord). Смысл шаблона прост: для работы с таблицами в базе данных решено было создать специальный класс, который бы выполнял все основные действия (CRUD).

Вот всё, что нужно для подключения: поместим в массив $dbConfig (тут будет 5 элементов):
host, user, pass, db, table.

Пусть функция setConfigDB заполнит нужными значениями $dbConfig.

protected $dbConfig = array();

    function setConfigDB($host, $user, $pass, $db, $table) {
        $this->dbConfig["host"] = $host;
        $this->dbConfig["user"] = $user;
        $this->dbConfig["pass"] = $pass;
        $this->dbConfig["db"] = $db;
        $this->dbConfig["table"] = $table;
    }

Теперь создадим метод подключения к БД:

protected function init_connected_db() {
        mysql_connect($this->dbConfig["host"], $this->dbConfig["user"], $this->dbConfig["pass"]);
        mysql_select_db($this->dbConfig["db"]);
        mysql_query("SET NAMES cp1251");
    }

Тут все как в книжке. Единственное, что mysql_query(«SET NAMES cp1251»); позволит читать данные в нужной кодировке. База данных настроена на эту кодировку.
Я не стал выбирать какие-то особенные имена, не стал придерживаться именования CRUD (Create, Update, Delete), а писал как есть.
Для того чтобы вставить запись, будем использовать эту функцию:

 function insert($keys, $values) {
        $table = $this->dbConfig["table"];
        $query = "INSERT INTO $table (";
        foreach ($keys as $value) {
            $query.="$value, ";
        }

        $query = substr($query, 0, -2);
        $query.=") VALUES (";
        foreach ($values as $value) {
            $query.="$value, ";
        }
        $query = substr($query, 0, -2);
        $query.=");";
        $this->init_connected_db();
        mysql_query($query);
    }

Главное потом надо не забыть, что здесь в качестве параметров передаются массивы. Foreach работает с ними, а без него проблемно создать запрос с несколькими полями и соответствующими значениями. Параметр $key у нас принимает имена полей, параметр $value — значения, которые надо записать в соответствующие поля. В функции два цикла, сначала пишем все поля, а потом все значения. Пользуемся стандартными возможностями PHP, чтобы получить нужную нам строку. В конце подключаемся к БД и выполняем запрос. Подключение к БД скрыто, чтобы программист только лишь передал нужную информацию в метод.

Для чтения данных и таблицы будем использовать две функции selectAll() и select($fields). По смыслу их можно объединить в одну, но по факту проще создать две.

 function selectAll() {
        $table = $this->dbConfig["table"];
        $query = "SELECT * FROM $table;";
        $this->init_connected_db();
        return $result = mysql_query($query);
    }

    function select($fields) {
        $table = $this->dbConfig["table"];
        $query = "SELECT ";
        foreach ($fields as $value) {
        $query.="$value, ";
        }
        $query = substr($query, 0, -2);
        $query.=" FROM $table";

        $this->init_connected_db();
        return $result = mysql_query($query);
    }

Так как инструкция SELECT вернет нам результат, то в return поместим $result = mysql_query($query);
Далее удаление.

function delete($key, $value) {
        $table = $this->dbConfig["table"];
        $query = "DELETE FROM $table WHERE $key=$value;";
        $this->init_connected_db();
        return $result = mysql_query($query);
    }

Метод — одноразовый. Один вызов — удалена одна строка. Известно, что инструкция DELETE возвращает число удаленных строк, для удобства вернем их return $result = mysql_query($query);.
Теперь обновим наши записи в табличке:

function update($key, $value, $where_key, $where_value) {
        $table = $this->dbConfig["table"];
        $query = "UPDATE $table SET $key =$value WHERE $where_key=$where_value;";
        $this->init_connected_db();
        return $result = mysql_query($query);
    }

Функция содержит 4 входных параметра $key, $value, $where_key, $where_value. Может показаться, что их слишком много, но с другой стороны инструкция UPDATE довольно подробная.

Так вот, $key=$value это то, что мы поместим на место старой записи, а $where_key и $where_value это то, где нам искать. То есть: находим строку с полем $where_key значение которого равно $where_value, в ней записываем значение $value в поле $key. Вроде сложно, но если прочесть команду в SQL, то сразу становиться понятным, что к чему.
Класс готов, теперь поработаем с экземпляром:

Создадим новый объект, запишем все необходимое для дальнейшей работы:

 $ar = new ActiveRecord(); 
 $ar->setConfigDB("localhost", "root", "", "prime", "tabl"); 

Далее вставим запись в табличку:

 	  $fields = array("text");
        $values = array("'Привет!'");
        $ar->insert($fields, $values); 

Не забываем, что в метод insert в качестве параметров передаются массивы.
Давайте теперь посмотрим, что у нас получилось в таблице:

 $result = $ar->selectAll(); 

И для просмотра результата, как в учебниках напишем цикл:

while ($row = mysql_fetch_array($result)) {

            echo " || " . $row['id'] . " => " . $row['text'];
        }

Здесь я специально не стал искать и придумывать способа вывода данных, так как основная задача нашего класса именно работа с БД. Ввод данных программист сам сформирует как ему надо, ну или сверстает отдельный класс для этого.
Теперь проведем выборку по конкретным полям. В моем случае одно.

	  $fields = array('id');
        $result = $ar->select($fields); 
       
        while ($row = mysql_fetch_array($result)) {
            echo $row['id'] . "; ";
        }

Что-нибудь удалим:

$ar->delete( "text","'Привет!'"); 
        $result = $ar->selectAll();
  

И обновим:

$ar->update("text", "'Пока!'", "id", 57); .

В общем всё. Получилось то, что хотелось бы считать приемлемым для работы. Относить этот класс к настоящим Active Record или нет, не знаю. Но уверен, что в столь нехитрой, а местами даже незатейливой реализации, его можно применять в простых проектах. А если хорошенько поработать над ним, то и в сложных ему найдётся место.

Автор: shumak93

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js