Русскоязычная документация находится тут
You can download it as an archive, clone from this site, or download via composer (link to packagist.org):
composer require krugozor/database
krugozor/database
?krugozor/database
is a PHP >= 8.0 class library for simple, convenient, fast and secure work with the MySql database, using
the PHP extension mysqli.
The main disadvantages of all libraries for working with the mysql database in PHP are:
int
and float
.krugozor/database
is a class for working with MySqlmysqli
and mysqli_result
mechanisms to create the methods you need to work with.krugozor/database
library?Most wrappers for various database drivers are a bunch of useless code with a disgusting architecture. Their authors, not understanding the practical purpose of their wrappers themselves, turn them into a kind of builders queries (sql builder), ActiveRecord libraries and other ORM solutions.
The krugozor/database
library is none of the above. This is just a convenient tool for working with regular SQL within the framework
MySQL DBMS - and no more!
Placeholders — special typed markers that are written in the SQL query string instead of explicit values (query parameters). And the values themselves are passed "later", as subsequent arguments to the main a method that executes a SQL query:
$result = $db->query(
"SELECT * FROM `users` WHERE `name` = '?s' AND `age` = ?i",
"d'Artagnan", 41
);
SQL query parameters passed through the placeholders system are processed by special escaping mechanisms, in
depending on the type of placeholders. Those. you no longer need to wrap variables in escaping functions
type mysqli_real_escape_string()
or cast them to a numeric type as before:
<?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");
Now it has become easy to write queries, quickly, and most importantly, the krugozor/database
library completely prevents any possible
SQL injections.
The types of fillers and their purposes are described below. Before getting acquainted with the types of fillers, it is necessary to understand how the library mechanism works.
PHP is a weakly typed language and an ideological dilemma arose when developing this library. Let's imagine that we have a table with the following structure:
`name` varchar not null
`flag` tinyint not null
and the library MUST (for some reason, possibly beyond the developer's control) execute the following request:
$db->query(
"INSERT INTO `t` SET `name` = '?s', `flag` = ?i",
null, false
);
In this example, an attempt is made to write a null
value to the not null
text field name
, and a false
boolean type to the flag
numeric field. What should we do in this situation?
false
value for the tinyint
column as the value 0
, and null
as an empty string for the name
column?In view of the questions raised, it was decided to implement two operating modes in this library.
Mysql::MODE_STRICT
mode, the argument type must match the placeholder type. For example, an attempt to pass the value 55.5
or '55.5'
as an argument for an integer placeholder ?i
will result in an exception being thrown:// 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
mode is set by default and is a "tolerant" mode - if the placeholder type and the argument type do not match, it does not throw an exception, but tryes to convert the argument to the desired placeholder type using the PHP language itself. By the way, I, as the author of the library, always use this particular mode, I have never used strict mode (Mysql::MODE_STRICT
) in real work, but perhaps you will need it specifically.The following transformations are allowed in Mysql::MODE_TRANSFORM
:
int
(placeholder ?i
)
string
and double
typesbool
TRUE is converted to int(1)
, FALSE is converted to int(0)
null
is converted to int(0)
double
(placeholder ?d
)
string
and int
typesbool
TRUE becomes float(1)
, FALSE becomes float(0)
null
is converted to float(0)
string
(placeholder ?s
)
bool
TRUE is converted to string(1) "1"
, FALSE is converted to string(1) "0"
. This behavior is different from casting bool
to int
in PHP, as often, in practice, the boolean type is written in MySql as a number.numeric
value is converted to a string according to PHP's conversion rulesnull
is converted to string(0) ""
null
(placeholder ?n
)
krugozor/database
library??i
— integer placeholder$db->query(
'SELECT * FROM `users` WHERE `id` = ?i', 123
);
SQL query after template conversion:
SELECT * FROM `users` WHERE `id` = 123
ATTENTION! If you operate on numbers that are outside the limits of PHP_INT_MAX
, then:
?s
(see below). The point is that numbers beyond
limits PHP_INT_MAX
, PHP interprets as floating point numbers. The library parser will try to convert
parameter to type int
, as a result "the result will be undefined, since the float does not have sufficient precision to
return the correct result. In this case, neither a warning nor even a remark will be displayed!” — php.net.?d
— floating point placeholder$db->query(
'SELECT * FROM `prices` WHERE `cost` IN (?d, ?d)',
12.56, '12.33'
);
SQL query after template conversion:
SELECT * FROM `prices` WHERE `cost` IN (12.56, 12.33)
ATTENTION! If you are using a library to work with the double
data type, set the appropriate locale so that
If the separator of the integer and fractional parts were the same both at the PHP level and at the DBMS level.
?s
— string type placeholderThe argument values are escaped using the mysqli::real_escape_string()
method:
$db->query(
'SELECT "?s"',
"You are all fools, and I am d'Artagnan!"
);
SQL query after template conversion:
SELECT "You are all fools, and I am d'Artagnan!"
?S
— string type placeholder for substitution in the SQL LIKE operatorArgument values are escaped using the mysqli::real_escape_string()
method + escaping special characters used in the LIKE operator (%
and _
):
$db->query('SELECT "?S"', '% _');
SQL query after template conversion:
SELECT "% _"
?n
— placeholder NULL
typeThe value of any arguments is ignored, placeholders are replaced with the string NULL
in the SQL query:
$db->query('SELECT ?n', 123);
SQL query after template conversion:
SELECT NULL
?A*
— associative set placeholder from an associative array, generating a sequence of pairs of the form key = value
where the character *
is one of the placeholders:
i
(integer placeholder)d
(float placeholder)s
(string type placeholder)the rules for conversion and escaping are the same as for the single scalar types described above. Example:
$db->query(
'INSERT INTO `test` SET ?Ai',
['first' => '123', 'second' => 456]
);
SQL query after template conversion:
INSERT INTO `test` SET `first` = "123", `second` = "456"
?a*
- set placeholder from a simple (or also associative) array, generating a sequence of valueswhere *
is one of the types:
i
(integer placeholder)d
(float placeholder)s
(string type placeholder)the rules for conversion and escaping are the same as for the single scalar types described above. Example:
$db->query(
'SELECT * FROM `test` WHERE `id` IN (?ai)',
[123, 456]
);
SQL query after template conversion:
SELECT * FROM `test` WHERE `id` IN ("123", "456")
?A[?n, ?s, ?i, ...]
— associative set placeholder with an explicit indication of the type and number of arguments, generating a sequence of key = value
pairsExample:
$db->query(
'INSERT INTO `users` SET ?A[?i, "?s"]',
['age' => 41, 'name' => "d'Artagnan"]
);
SQL query after template conversion:
INSERT INTO `users` SET `age` = 41,`name` = "d'Artagnan"
?a[?n, ?s, ?i, ...]
— set placeholder with an explicit indication of the type and number of arguments, generating a sequence of valuesExample:
$db->query(
'SELECT * FROM `users` WHERE `name` IN (?a["?s", "?s"])',
['Daniel O"Neill', "d'Artagnan"]
);
SQL query after template conversion:
SELECT * FROM `users` WHERE `name` IN ("Daniel O"Neill", "d'Artagnan")
?f
— table or field name placeholderThis placeholder is intended for cases where the name of a table or field is passed in the query as a parameter. Field and table names are framed with an apostrophe:
$db->query(
'SELECT ?f FROM ?f',
'name',
'database.table_name'
);
SQL query after template conversion:
SELECT `name` FROM `database`.`table_name`
The library requires the programmer to follow the SQL syntax. This means that the following query will not work:
$db->query(
'SELECT CONCAT("Hello, ", ?s, "!")',
'world'
);
— placeholder ?s
must be enclosed in single or double quotes:
$db->query(
'SELECT concat("Hello, ", "?s", "!")',
'world'
);
SQL query after template conversion:
SELECT concat("Hello, ", "world", "!")
For those who are used to working with PDO, this will seem strange, but implementing a mechanism that determines whether it is necessary to enclose the placeholder value in quotes in one case or not is a very non-trivial task that requires writing a whole parser.
See in file ./console/tests.php