Давным давно, когда я только начинал изучать PHP и тонкости составления запросов MySQL (2011 год) у меня возникла мысль написать обертку для MySQLi наподобие Doctrine для упрощения синтаксиса обращения к базе данных. На дворе уже 2019 и решил поделиться своим велосипедом на тему ORM.
И так, это DBX — движок базы данных MySQL для PHP на основе библиотеки MySQLi основанный на запросах вида структурного описания таблиц и полей базы данных в виде обычного массива с функцией статического кэширования запросов и автообновления хэша статики.
Вопреки всеобщей любви к PDO, была выбрана именно легковесная MySQLi функциональность, которая мягче и проще программируется и более лаконично вписывается в предложенное API DBX. Я даже не использовал composer, потому что у меня нет ни одного проекта, где я использую сторонние зависимости кроме самописных.
Собственно, рассмотрим пример объявления структуры простейшей тестовой базы данных и ее таблиц. Для начала подключим саму библиотеку с классом и отправим данные авторизации с хостом базы данных:
Теперь представим, что нам нужно описать и создать таблицу в БД используя синтаксис обычного массива PHP:
Здесь синтаксис простой. Я не использовал строгую типизацию и выбрал просто значения TEXT, NUMBER и TYMESTAMP. Конечно же, для более «рульной» структуры таблицы используется ключевое поле ID с автоинкрементом (не встречал случаев в реальных проектах, когда задание автоинкремента и ключа мешает проектированию запросов и связей таблиц). Для указания может ли поле быть пустым указывается параметр fill => true.
Типы запросов DataBaseX очень просты и содержат основные методы вроде select, insert, delete, update, drop, truncate и так далее.
К примеру запрос для создания таблицы:
Или запрос добавления данных и структуры столбцов может выглядеть вот так:
Структура массива позволяет однажды описать базу данных и в последующем лишь манипулировать полями value для изменения данных, которые используются для формирования запросов.
Вот пример update инструкции, которую я упраздню в следующем примере:
Мне показалось, что использование полей criterion_field и criterion_value усложняет систему, поэтому я создал запрос, который автоматически либо добавляет данные в БД, если они еще не были созданы, либо обновляет существующие данные. Этот запрос я назвал INJECT QUERY и вызывается он префиксом «in»:
Работает это на низком уровне так:
Все остальные запросы простейшие и описывать их не имеет смысла(смотрите примеры в файле тестов index.php), но я не могу не показать как работает запрос SELECT:
Здесь с использованием префикса «s» можно сгруппировать параметры запроса s|field_id(order)|asc(direction)|100(limit)|0(offset).
Кроме прочего DBX обладает такой отличительностью, как встроенный файловый кэш на базе JSON статики. Каждый запрос изменения (INSERT, UPDATE, DELETE, TRUNCATE) вызывает пресчёт хэша в таблице хэшей кэша и автоматически обновляет статический кэш, что позволяет не думать о нагрузке на запросы SELECT.
В будущем я планирую до развить движок DBX и расширить возможности конструктора SQL запросов системой конфигурации UNION и JOIN, а также добавить новую из MySQL 8 поддержку базы данных на типе JSON структуры.
Сейчас DBX используется в моей системе управления контентом RevolveR и показывает неплохие характеристики (весь сайт при условии наличия обновленного кэша инициализируется одним запросом к БД и потребляет около 0.7 Mb оперативной памяти интерпретатора). А также мне очень удобно видеть всю структуру БД в одном отдельном файле, что в разы ускоряет наращивание и проектирование новых модулей.
Репозиторий проекта: DBX v1.1.1 на GitHub.
И так, это DBX — движок базы данных MySQL для PHP на основе библиотеки MySQLi основанный на запросах вида структурного описания таблиц и полей базы данных в виде обычного массива с функцией статического кэширования запросов и автообновления хэша статики.
Вопреки всеобщей любви к PDO, была выбрана именно легковесная MySQLi функциональность, которая мягче и проще программируется и более лаконично вписывается в предложенное API DBX. Я даже не использовал composer, потому что у меня нет ни одного проекта, где я использую сторонние зависимости кроме самописных.
Собственно, рассмотрим пример объявления структуры простейшей тестовой базы данных и ее таблиц. Для начала подключим саму библиотеку с классом и отправим данные авторизации с хостом базы данных:
require_once './DBX.php';
$dbx_data = ['localhost', 'root', 'root', 'dbx_test', '8889'];
Теперь представим, что нам нужно описать и создать таблицу в БД используя синтаксис обычного массива PHP:
<?php
/**
* CREATE TABLE EXAMPLE
*/
$table_1 = 'example'; // table name
$query_1 = 'c'; // create table sql
$fields_1 = [
'field_id' => [
'type' => 'num', // int
'auto' => true, // auto increment
'length' => 255,
'fill' => true // not null
],
'field_text' => [
'type' => 'text', // varchar
'length' => 255,
'fill' => true
],
'field_date' => [
'type' => 'time', // TIMESTAMP
'value' => date('Y-m-d')
]
];
?>
Здесь синтаксис простой. Я не использовал строгую типизацию и выбрал просто значения TEXT, NUMBER и TYMESTAMP. Конечно же, для более «рульной» структуры таблицы используется ключевое поле ID с автоинкрементом (не встречал случаев в реальных проектах, когда задание автоинкремента и ключа мешает проектированию запросов и связей таблиц). Для указания может ли поле быть пустым указывается параметр fill => true.
Типы запросов DataBaseX очень просты и содержат основные методы вроде select, insert, delete, update, drop, truncate и так далее.
К примеру запрос для создания таблицы:
// perform queries
$dbx::query("c", $table_1, $fields_1);
Или запрос добавления данных и структуры столбцов может выглядеть вот так:
// fields values for table_1 example
$fields_2 = [
'field_id' => [
'value' => 456
],
'field_text' => [
'value' => 'I have to add into my table'
],
'field_date' => [
'value' => date('Y-m-d')
]
];
// perform queries
$dbx::query('i', $table_1, $fields_2);
Структура массива позволяет однажды описать базу данных и в последующем лишь манипулировать полями value для изменения данных, которые используются для формирования запросов.
Вот пример update инструкции, которую я упраздню в следующем примере:
// fields values for table_1 example
$fields_3 = [
'field_id' => [
'value' => 456
],
'field_text' => [
'new_value' => 'I was updated',
'criterion_field' => 'field_id',
'criterion_value' => 456
],
'field_date' => [
'value' => date('Y-m-d')
]
];
// perform queries
$dbx::query('u', $table_1, $fields_3);
Мне показалось, что использование полей criterion_field и criterion_value усложняет систему, поэтому я создал запрос, который автоматически либо добавляет данные в БД, если они еще не были созданы, либо обновляет существующие данные. Этот запрос я назвал INJECT QUERY и вызывается он префиксом «in»:
// fields values for table_1 example
$fields_2 = [
'field_id' => [
'value' => 0
],
'field_text' => [
'value' => 'Yo if field_id = 0 it\'s an insert or if id exists it\'s an update'
],
'field_date' => [
'value' => date('Y-m-d')
]
];
// perform queries
$dbx::query('in', $table_1, $fields_2);
Работает это на низком уровне так:
INSERT INTO `revolver__comments` (`field_id`, `field_content`)
VALUES ('5', 'TEST UPDATE')
ON DUPLICATE KEY UPDATE `field_id`='5', `field_content`='TEST UPDATE';
Все остальные запросы простейшие и описывать их не имеет смысла(смотрите примеры в файле тестов index.php), но я не могу не показать как работает запрос SELECT:
<?php
// perform queries
$dbx::query('s|field_id|asc|100|0', $table_1, $fields_1);
?>
<?php
// print structure
print '<h2>DBX STRUCTURE</h2>';
print '<pre><code>';
print_r( $fields_1 );
print '</code></pre>';
// print result
print '<h2>DBX QUERY RESULT</h2>';
print '<pre><code>';
print_r( $dbx::$result );
print '</code><pre><hr />';
?>
Здесь с использованием префикса «s» можно сгруппировать параметры запроса s|field_id(order)|asc(direction)|100(limit)|0(offset).
Кроме прочего DBX обладает такой отличительностью, как встроенный файловый кэш на базе JSON статики. Каждый запрос изменения (INSERT, UPDATE, DELETE, TRUNCATE) вызывает пресчёт хэша в таблице хэшей кэша и автоматически обновляет статический кэш, что позволяет не думать о нагрузке на запросы SELECT.
В будущем я планирую до развить движок DBX и расширить возможности конструктора SQL запросов системой конфигурации UNION и JOIN, а также добавить новую из MySQL 8 поддержку базы данных на типе JSON структуры.
Сейчас DBX используется в моей системе управления контентом RevolveR и показывает неплохие характеристики (весь сайт при условии наличия обновленного кэша инициализируется одним запросом к БД и потребляет около 0.7 Mb оперативной памяти интерпретатора). А также мне очень удобно видеть всю структуру БД в одном отдельном файле, что в разы ускоряет наращивание и проектирование новых модулей.
Репозиторий проекта: DBX v1.1.1 на GitHub.