Русскоязычная документация находится здесь
Вы можете скачать его в виде архива, клонировать с этого сайта или скачать через композитор (ссылка на packagegist.org):
composer require krugozor/database
krugozor/database
? krugozor/database
— библиотека классов PHP >= 8.0 для простой, удобной, быстрой и безопасной работы с базой данных MySql, с использованием PHP-расширения mysqli.
Основными недостатками всех библиотек для работы с базой данных mysql на PHP являются:
int
и float
.krugozor/database
— класс для работы с MySqlmysqli
и mysqli_result
для создания методов, с которыми вам нужно работать.krugozor/database
?Большинство оберток для различных драйверов баз данных — это куча бесполезного кода с отвратительной архитектурой. Их авторы, сами не понимая практического назначения своих оберток, превращают их в своеобразные построители запросов (sql builder), библиотеки ActiveRecord и прочие ORM-решения.
Библиотека krugozor/database
не является ничем из вышеперечисленного. Это всего лишь удобный инструмент для работы с обычным SQL в рамках СУБД MySQL – и не более!
Заполнители — специальные типизированные маркеры , которые записываются в строку SQL-запроса вместо явных значений (параметров запроса) . А сами значения передаются «позже», как последующие аргументы основному методу, выполняющему SQL-запрос:
$ result = $ db -> query (
" SELECT * FROM `users` WHERE `name` = '?s' AND `age` = ?i " ,
" d'Artagnan " , 41
);
Параметры SQL-запроса, передаваемые через систему заполнителей , обрабатываются специальными механизмами экранирования в зависимости от типа заполнителей. Те. вам больше не нужно заключать переменные в экранирующие функции типа mysqli_real_escape_string()
или приводить их к числовому типу, как раньше:
<?php
// Previously, before each request to the DBMS, we did
// something like this (and many people still don't do it):
$ id = ( int ) $ _POST [ ' id ' ];
$ value = mysqli_real_escape_string ( $ mysql , $ _POST [ ' value ' ]);
$ result = mysqli_query ( $ mysql , " SELECT * FROM `t` WHERE `f1` = ' $ value ' AND `f2` = $ id " );
Теперь писать запросы стало легко, быстро, а главное библиотека krugozor/database
полностью предотвращает любые возможные SQL-инъекции.
Виды наполнителей и их назначение описаны ниже. Прежде чем знакомиться с видами наполнителей, необходимо понять, как работает механизм библиотеки.
PHP — слабо типизированный язык, и при разработке этой библиотеки возникла идеологическая дилемма. Представим, что у нас есть таблица следующей структуры:
` name ` varchar not null
` flag ` tinyint not null
и библиотека ДОЛЖНА (по какой-то причине, возможно, не зависящей от разработчика) выполнить следующий запрос:
$ db -> query (
" INSERT INTO `t` SET `name` = '?s', `flag` = ?i " ,
null , false
);
В этом примере предпринята попытка записать null
значение в not null
текстовое поле name
и false
логический тип в числовое поле flag
. Что нам делать в этой ситуации?
false
для столбца tinyint
как значение 0
, а null
— как пустую строку для столбца name
?Ввиду возникших вопросов было решено реализовать в данной библиотеке два режима работы.
Mysql::MODE_STRICT
тип аргумента должен соответствовать типу заполнителя . Например, попытка передать значение 55.5
или '55.5'
в качестве аргумента для целочисленного заполнителя ?i
приведет к выдаче исключения: // set strict mode
$ db -> setTypeMode (Mysql:: MODE_STRICT );
// this expression will not be executed, an exception will be thrown:
// attempt to specify a value of type "integer" for placeholder of type "double" in query template "SELECT ?i"
$ db -> query ( ' SELECT ?i ' , 55.5 );
Mysql::MODE_TRANSFORM
установлен по умолчанию и является «толерантным» режимом — если тип заполнителя и тип аргумента не совпадают, он не генерирует исключение, а пытается преобразовать аргумент в желаемый тип заполнителя, используя метод Сам язык PHP . Кстати, я, как автор библиотеки, всегда использую именно этот режим, я никогда не использовал строгий режим ( Mysql::MODE_STRICT
) в реальной работе, но возможно он понадобится конкретно вам. В Mysql::MODE_TRANSFORM
разрешены следующие преобразования:
int
(заполнитель ?i
)string
, так и в double
типеbool
TRUE преобразуется в int(1)
, FALSE преобразуется в int(0)
null
преобразуется в int(0)
double
(заполнитель ?d
)string
, так и в типах int
bool
TRUE становится float(1)
, FALSE становится float(0)
null
преобразуется в float(0)
string
(заполнитель ?s
)bool
TRUE преобразуется в string(1) "1"
, FALSE преобразуется в string(1) "0"
. Такое поведение отличается от приведения bool
к int
в PHP, поскольку на практике логический тип часто записывается в MySql как число.numeric
значение преобразуется в строку в соответствии с правилами преобразования PHPnull
преобразуется в string(0) ""
null
(заполнитель ?n
)krugozor/database
? ?i
— целочисленный заполнитель $ db -> query (
' SELECT * FROM `users` WHERE `id` = ?i ' , 123
);
SQL-запрос после преобразования шаблона:
SELECT * FROM ` users ` WHERE ` id ` = 123
ВНИМАНИЕ! Если вы оперируете числами, выходящими за пределы PHP_INT_MAX
, то:
?s
(см. ниже). Дело в том, что числа, выходящие за пределы PHP_INT_MAX
, PHP интерпретирует как числа с плавающей запятой. Парсер библиотеки попытается преобразовать параметр в тип int
, в результате « результат будет неопределенным, так как число с плавающей запятой не имеет достаточной точности, чтобы вернуть правильный результат. В этом случае не будет отображено ни предупреждение, ни даже замечание». ! » — php.net. ?d
— заполнитель с плавающей запятой $ db -> query (
' SELECT * FROM `prices` WHERE `cost` IN (?d, ?d) ' ,
12.56 , ' 12.33 '
);
SQL-запрос после преобразования шаблона:
SELECT * FROM ` prices ` WHERE ` cost ` IN ( 12 . 56 , 12 . 33 )
ВНИМАНИЕ! Если вы используете библиотеку для работы с типом данных double
, установите соответствующую локаль так, чтобы разделитель целой и дробной частей был одинаковым как на уровне PHP, так и на уровне СУБД.
?s
— заполнитель строкового типа Значения аргументов экранируются с помощью метода mysqli::real_escape_string()
:
$ db -> query (
' SELECT "?s" ' ,
" You are all fools, and I am d'Artagnan! "
);
SQL-запрос после преобразования шаблона:
SELECT " You are all fools, and I am d'Artagnan! "
?S
— заполнитель строкового типа для подстановки в операторе SQL LIKE. Значения аргументов экранируются с помощью mysqli::real_escape_string()
+ экранирования специальных символов, используемых в операторе LIKE ( %
и _
):
$ db -> query ( ' SELECT "?S" ' , ' % _ ' );
SQL-запрос после преобразования шаблона:
SELECT " % _ "
?n
— заполнитель типа NULL
Значение любых аргументов игнорируется, заполнители в SQL-запросе заменяются строкой NULL
:
$ db -> query ( ' SELECT ?n ' , 123 );
SQL-запрос после преобразования шаблона:
SELECT NULL
?A*
— заполнитель ассоциативного набора из ассоциативного массива, генерирующий последовательность пар вида key = value
где символ *
является одним из заполнителей:
i
(целочисленный заполнитель)d
(плавающий заполнитель)s
(заполнитель строкового типа)правила преобразования и экранирования такие же, как и для одиночных скалярных типов, описанных выше. Пример:
$ db -> query (
' INSERT INTO `test` SET ?Ai ' ,
[ ' first ' => ' 123 ' , ' second ' => 456 ]
);
SQL-запрос после преобразования шаблона:
INSERT INTO ` test ` SET ` first ` = " 123 " , ` second ` = " 456 "
?a*
- установить заполнитель из простого (или также ассоциативного) массива, генерируя последовательность значений где *
— один из типов:
i
(целочисленный заполнитель)d
(плавающий заполнитель)s
(заполнитель строкового типа)правила преобразования и экранирования такие же, как и для одиночных скалярных типов, описанных выше. Пример:
$ db -> query (
' SELECT * FROM `test` WHERE `id` IN (?ai) ' ,
[ 123 , 456 ]
);
SQL-запрос после преобразования шаблона:
SELECT * FROM ` test ` WHERE ` id ` IN ( " 123 " , " 456 " )
?A[?n, ?s, ?i, ...]
— заполнитель ассоциативного набора с явным указанием типа и количества аргументов, генерирующий последовательность пар key = value
Пример:
$ db -> query (
' INSERT INTO `users` SET ?A[?i, "?s"] ' ,
[ ' age ' => 41 , ' name ' => " d'Artagnan " ]
);
SQL-запрос после преобразования шаблона:
INSERT INTO ` users ` SET ` age ` = 41 , ` name ` = " d'Artagnan "
?a[?n, ?s, ?i, ...]
— установка заполнителя с явным указанием типа и количества аргументов, генерирующая последовательность значенийПример:
$ db -> query (
' SELECT * FROM `users` WHERE `name` IN (?a["?s", "?s"]) ' ,
[ ' Daniel O"Neill ' , " d'Artagnan " ]
);
SQL-запрос после преобразования шаблона:
SELECT * FROM ` users ` WHERE ` name ` IN ( " Daniel O " Neill " , " d ' Artagnan")
?f
— заполнитель имени таблицы или поляЭтот заполнитель предназначен для случаев, когда имя таблицы или поля передается в запросе в качестве параметра. Имена полей и таблиц обрамляются апострофом:
$ db -> query (
' SELECT ?f FROM ?f ' ,
' name ' ,
' database.table_name '
);
SQL-запрос после преобразования шаблона:
SELECT ` name ` FROM ` database ` . ` table_name `
Библиотека требует от программиста соблюдения синтаксиса SQL. Это означает, что следующий запрос не будет работать:
$ db -> query (
' SELECT CONCAT("Hello, ", ?s, "!") ' ,
' world '
);
— заполнитель ?s
должен быть заключен в одинарные или двойные кавычки:
$ db -> query (
' SELECT concat("Hello, ", "?s", "!") ' ,
' world '
);
SQL-запрос после преобразования шаблона:
SELECT concat( " Hello, " , " world " , " ! " )
Для тех, кто привык работать с PDO, это покажется странным, но реализация механизма, определяющего, нужно ли заключать значение-заполнитель в кавычки в одном случае или нет, — весьма нетривиальная задача, требующая написания целого парсера. .
См. файл ./console/tests.php.