Русскоязычная документация находится тут
您可以將其作為存檔下載,從該網站克隆,或透過 Composer 下載(連結到 packagist.org):
composer require krugozor/database
krugozor/database
? krugozor/database
是一個 PHP >= 8.0 類別函式庫,使用 PHP 擴充 mysqli 來簡單、方便、快速、安全地使用 MySql 資料庫。
在 PHP 中使用 mysql 資料庫的所有函式庫的主要缺點是:
int
和float
。krugozor/database
是一個用於使用 MySql 的類mysqli
和mysqli_result
機制來建立您需要使用的方法。krugozor/database
庫?大多數各種資料庫驅動程式的包裝器都是一堆無用的程式碼,具有令人厭惡的架構。他們的作者並不理解包裝器本身的實際用途,而是將它們轉變為建構器查詢(sql 建構器)、ActiveRecord 函式庫和其他 ORM 解決方案。
krugozor/database
庫不是以上任何一個。這只是一個在 MySQL DBMS 框架內使用常規 SQL 的便利工具 - 僅此而已!
佔位符—寫入 SQL 查詢字串而不是明確值(查詢參數)中的特殊類型標記。並且值本身「稍後」作為後續參數傳遞給執行 SQL 查詢的 main 方法:
$ 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
數字欄位。在這種情況下我們該怎麼辦?
tinyint
列的false
值視為值0
,並將name
列的null
視為空字串?針對提出的問題,決定本館實施兩種營運模式。
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"
。這種行為與 PHP 中將bool
轉換為int
不同,在實作中,布林類型在 MySql 中通常被寫為數字。numeric
轉換為字串null
轉換為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
類型,結果「結果將是未定義的,因為浮點數沒有足夠的精度來傳回正確的結果。在這種情況下,既不會顯示警告,也不會顯示註! ?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 層級和 DBMS 層級相同。
?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