Русскоязычная документация находится тут
Você pode baixá-lo como um arquivo, cloná-lo neste site ou baixá-lo via compositor (link para packagist.org):
composer require krugozor/database
krugozor/database
? krugozor/database
é uma biblioteca de classes PHP >= 8.0 para trabalho simples, conveniente, rápido e seguro com o banco de dados MySql, usando a extensão PHP mysqli.
As principais desvantagens de todas as bibliotecas para trabalhar com banco de dados mysql em PHP são:
int
e float
.krugozor/database
é uma classe para trabalhar com MySqlmysqli
e mysqli_result
para criar os métodos com os quais você precisa trabalhar.krugozor/database
?A maioria dos wrappers para vários drivers de banco de dados são um monte de código inútil com uma arquitetura nojenta. Seus autores, não entendendo o propósito prático de seus próprios wrappers, os transformam em uma espécie de consultas de construtores (construtor sql), bibliotecas ActiveRecord e outras soluções ORM.
A biblioteca krugozor/database
não é nenhuma das opções acima. Esta é apenas uma ferramenta conveniente para trabalhar com SQL regular dentro da estrutura MySQL DBMS - e nada mais!
Espaços reservados — marcadores digitados especiais que são gravados na string de consulta SQL em vez de valores explícitos (parâmetros de consulta) . E os próprios valores são passados "mais tarde", como argumentos subsequentes ao método principal que executa uma consulta SQL:
$ result = $ db -> query (
" SELECT * FROM `users` WHERE `name` = '?s' AND `age` = ?i " ,
" d'Artagnan " , 41
);
Os parâmetros de consulta SQL passados pelo sistema de marcadores são processados por mecanismos de escape especiais, dependendo do tipo de marcadores. Aqueles. você não precisa mais agrupar variáveis em funções de escape do tipo mysqli_real_escape_string()
ou convertê-las em um tipo numérico como antes:
<?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 " );
Agora ficou fácil escrever consultas rapidamente e, o mais importante, a biblioteca krugozor/database
evita completamente quaisquer possíveis injeções de SQL.
Os tipos de enchimentos e suas finalidades são descritos abaixo. Antes de se familiarizar com os tipos de preenchimentos, é necessário entender como funciona o mecanismo da biblioteca.
PHP é uma linguagem de tipo fraco e surgiu um dilema ideológico ao desenvolver esta biblioteca. Vamos imaginar que temos uma tabela com a seguinte estrutura:
` name ` varchar not null
` flag ` tinyint not null
e a biblioteca DEVE (por algum motivo, possivelmente além do controle do desenvolvedor) executar a seguinte solicitação:
$ db -> query (
" INSERT INTO `t` SET `name` = '?s', `flag` = ?i " ,
null , false
);
Neste exemplo, é feita uma tentativa de gravar um valor null
no campo de texto not null
name
e um tipo booleano false
no campo numérico flag
. O que devemos fazer nesta situação?
false
da coluna tinyint
como o valor 0
e null
como uma string vazia para a coluna name
?Face às questões levantadas, optou-se por implementar dois modos de funcionamento nesta biblioteca.
Mysql::MODE_STRICT
, o tipo de argumento deve corresponder ao tipo de espaço reservado . Por exemplo, uma tentativa de passar o valor 55.5
ou '55.5'
como argumento para um espaço reservado de número inteiro ?i
resultará no lançamento de uma exceção: // 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
é definido por padrão e é um modo "tolerante" - se o tipo de espaço reservado e o tipo de argumento não corresponderem, ele não lança uma exceção, mas tenta converter o argumento para o tipo de espaço reservado desejado usando o A própria linguagem PHP . A propósito, eu, como autor da biblioteca, sempre uso esse modo específico, nunca usei o modo estrito ( Mysql::MODE_STRICT
) no trabalho real, mas talvez você precise dele especificamente. As seguintes transformações são permitidas em Mysql::MODE_TRANSFORM
:
int
(espaço reservado ?i
)string
e double
bool
TRUE é convertido em int(1)
, FALSE é convertido em int(0)
null
é convertido em int(0)
double
(espaço reservado ?d
)string
e int
bool
TRUE torna-se float(1)
, FALSE torna-se float(0)
null
é convertido em float(0)
string
(espaço reservado ?s
)bool
TRUE é convertido em string(1) "1"
, FALSE é convertido em string(1) "0"
. Este comportamento é diferente de converter bool
para int
em PHP, já que muitas vezes, na prática, o tipo booleano é escrito em MySql como um número.numeric
é convertido em uma string de acordo com as regras de conversão do PHPnull
é convertido em string(0) ""
null
(espaço reservado ?n
)krugozor/database
? ?i
— espaço reservado para número inteiro $ db -> query (
' SELECT * FROM `users` WHERE `id` = ?i ' , 123
);
Consulta SQL após conversão do modelo:
SELECT * FROM ` users ` WHERE ` id ` = 123
ATENÇÃO! Se você operar com números que estão fora dos limites do PHP_INT_MAX
, então:
?s
(veja abaixo). A questão é que números além dos limites PHP_INT_MAX
, o PHP interpreta como números de ponto flutuante. O analisador da biblioteca tentará converter o parâmetro para o tipo int
, como resultado " o resultado será indefinido, pois o float não possui precisão suficiente para retornar o resultado correto. Neste caso, nem um aviso nem mesmo uma observação serão exibidos ! ”- php.net. ?d
— espaço reservado para ponto flutuante $ db -> query (
' SELECT * FROM `prices` WHERE `cost` IN (?d, ?d) ' ,
12.56 , ' 12.33 '
);
Consulta SQL após conversão do modelo:
SELECT * FROM ` prices ` WHERE ` cost ` IN ( 12 . 56 , 12 . 33 )
ATENÇÃO! Se você estiver usando uma biblioteca para trabalhar com o tipo de dados double
, defina o código de idioma apropriado para que o separador das partes inteiras e fracionárias seja o mesmo tanto no nível do PHP quanto no nível do SGBD.
?s
— espaço reservado para tipo de string Os valores dos argumentos são escapados usando o método mysqli::real_escape_string()
:
$ db -> query (
' SELECT "?s" ' ,
" You are all fools, and I am d'Artagnan! "
);
Consulta SQL após conversão do modelo:
SELECT " You are all fools, and I am d'Artagnan! "
?S
— espaço reservado do tipo string para substituição no operador SQL LIKE Os valores dos argumentos são escapados usando o método mysqli::real_escape_string()
+ caracteres especiais de escape usados no operador LIKE ( %
e _
):
$ db -> query ( ' SELECT "?S" ' , ' % _ ' );
Consulta SQL após conversão do modelo:
SELECT " % _ "
?n
— espaço reservado tipo NULL
O valor de qualquer argumento é ignorado, os espaços reservados são substituídos pela string NULL
na consulta SQL:
$ db -> query ( ' SELECT ?n ' , 123 );
Consulta SQL após conversão do modelo:
SELECT NULL
?A*
— espaço reservado para conjunto associativo de uma matriz associativa, gerando uma sequência de pares no formato key = value
onde o caractere *
é um dos espaços reservados:
i
(espaço reservado para número inteiro)d
(espaço reservado flutuante)s
(espaço reservado do tipo string)as regras para conversão e escape são as mesmas dos tipos escalares únicos descritos acima. Exemplo:
$ db -> query (
' INSERT INTO `test` SET ?Ai ' ,
[ ' first ' => ' 123 ' , ' second ' => 456 ]
);
Consulta SQL após conversão do modelo:
INSERT INTO ` test ` SET ` first ` = " 123 " , ` second ` = " 456 "
?a*
- define placeholder a partir de um array simples (ou também associativo), gerando uma sequência de valores onde *
é um dos tipos:
i
(espaço reservado para número inteiro)d
(espaço reservado flutuante)s
(espaço reservado do tipo string)as regras para conversão e escape são as mesmas dos tipos escalares únicos descritos acima. Exemplo:
$ db -> query (
' SELECT * FROM `test` WHERE `id` IN (?ai) ' ,
[ 123 , 456 ]
);
Consulta SQL após conversão do modelo:
SELECT * FROM ` test ` WHERE ` id ` IN ( " 123 " , " 456 " )
?A[?n, ?s, ?i, ...]
— espaço reservado para conjunto associativo com indicação explícita do tipo e número de argumentos, gerando uma sequência de pares key = value
Exemplo:
$ db -> query (
' INSERT INTO `users` SET ?A[?i, "?s"] ' ,
[ ' age ' => 41 , ' name ' => " d'Artagnan " ]
);
Consulta SQL após conversão do modelo:
INSERT INTO ` users ` SET ` age ` = 41 , ` name ` = " d'Artagnan "
?a[?n, ?s, ?i, ...]
— define placeholder com indicação explícita do tipo e número de argumentos, gerando uma sequência de valoresExemplo:
$ db -> query (
' SELECT * FROM `users` WHERE `name` IN (?a["?s", "?s"]) ' ,
[ ' Daniel O"Neill ' , " d'Artagnan " ]
);
Consulta SQL após conversão do modelo:
SELECT * FROM ` users ` WHERE ` name ` IN ( " Daniel O " Neill " , " d ' Artagnan")
?f
— espaço reservado para nome de tabela ou campoEste placeholder é destinado aos casos em que o nome de uma tabela ou campo é passado na consulta como parâmetro. Os nomes dos campos e tabelas são delimitados por um apóstrofo:
$ db -> query (
' SELECT ?f FROM ?f ' ,
' name ' ,
' database.table_name '
);
Consulta SQL após conversão do modelo:
SELECT ` name ` FROM ` database ` . ` table_name `
A biblioteca exige que o programador siga a sintaxe SQL. Isso significa que a seguinte consulta não funcionará:
$ db -> query (
' SELECT CONCAT("Hello, ", ?s, "!") ' ,
' world '
);
— o espaço reservado ?s
deve ser colocado entre aspas simples ou duplas:
$ db -> query (
' SELECT concat("Hello, ", "?s", "!") ' ,
' world '
);
Consulta SQL após conversão do modelo:
SELECT concat( " Hello, " , " world " , " ! " )
Para quem está acostumado a trabalhar com PDO, isso pode parecer estranho, mas implementar um mecanismo que determine se é necessário colocar o valor do espaço reservado entre aspas em um caso ou não é uma tarefa nada trivial que requer escrever um analisador inteiro .
Veja no arquivo ./console/tests.php