Русскоязычная документация находится тут
คุณสามารถดาวน์โหลดเป็นไฟล์เก็บถาวร โคลนจากไซต์นี้ หรือดาวน์โหลดผ่านผู้แต่ง (ลิงก์ไปยัง packagist.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
Wrapper ส่วนใหญ่สำหรับไดรเวอร์ฐานข้อมูลต่างๆ เป็นกลุ่มโค้ดที่ไม่มีประโยชน์และมีสถาปัตยกรรมที่น่าขยะแขยง ผู้เขียนไม่เข้าใจจุดประสงค์ในทางปฏิบัติของ wrapper เอง จึงเปลี่ยนให้เป็นแบบสอบถามของผู้สร้าง (ตัวสร้าง sql) ไลบรารี ActiveRecord และโซลูชัน ORM อื่น ๆ
krugozor/database
ไม่ตรงกับข้อใดข้างต้น นี่เป็นเพียงเครื่องมือที่สะดวกสำหรับการทำงานกับ SQL ปกติภายในเฟรมเวิร์ก MySQL DBMS - และไม่มีอีกแล้ว!
ตัวยึดตำแหน่ง — เครื่องหมายชนิด พิเศษที่เขียนในสตริงการสืบค้น SQL แทนที่จะเป็นค่าที่ชัดเจน (พารามิเตอร์การสืบค้น) และค่าต่างๆ จะถูกส่งผ่าน "ภายหลัง" ซึ่งเป็นอาร์กิวเมนต์ที่ตามมาไปยังเมธอดหลักที่ดำเนินการแบบสอบถาม SQL:
$ result = $ db -> query (
" SELECT * FROM `users` WHERE `name` = '?s' AND `age` = ?i " ,
" d'Artagnan " , 41
);
พารามิเตอร์การสืบค้น SQL ที่ส่งผ่านระบบ ตัวยึดตำแหน่ง จะถูกประมวลผลโดยกลไกการ Escape พิเศษ ขึ้นอยู่กับประเภทของตัวยึดตำแหน่ง เหล่านั้น. คุณไม่จำเป็นต้องล้อมตัวแปรในการหลีกเลี่ยงฟังก์ชันประเภท 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 ดังที่ในทางปฏิบัติแล้ว ประเภทบูลีนจะเขียนเป็นตัวเลขใน MySqlnumeric
จะถูกแปลงเป็นสตริงตามกฎการแปลงของ 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
ดังนั้นผลลัพธ์ " ผลลัพธ์จะไม่ถูกกำหนด เนื่องจาก float ไม่มีความแม่นยำเพียงพอที่จะส่งคืนผลลัพธ์ที่ถูกต้อง ในกรณีนี้ จะไม่แสดงคำเตือนหรือหมายเหตุใด ๆ ! ” — 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 และที่ระดับ 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
ค่าของอาร์กิวเมนต์ใดๆ จะถูกละเว้น ตัวยึดตำแหน่งจะถูกแทนที่ด้วยสตริง NULL
ในแบบสอบถาม SQL:
$ db -> query ( ' SELECT ?n ' , 123 );
แบบสอบถาม SQL หลังจากการแปลงเทมเพลต:
SELECT NULL
?A*
— ตัวยึดชุดที่เชื่อมโยงจากอาร์เรย์ที่เชื่อมโยง ซึ่งสร้างลำดับคู่ของ key = value
โดยที่อักขระ *
เป็นหนึ่งในตัวยึดตำแหน่ง:
i
(ตัวยึดจำนวนเต็ม)d
(ตัวยึดตำแหน่งลอย)s
(ตัวยึดประเภทสตริง)กฎสำหรับการแปลงและการ Escape จะเหมือนกับกฎสำหรับประเภทสเกลาร์เดี่ยวที่อธิบายไว้ข้างต้น ตัวอย่าง:
$ db -> query (
' INSERT INTO `test` SET ?Ai ' ,
[ ' first ' => ' 123 ' , ' second ' => 456 ]
);
แบบสอบถาม SQL หลังจากการแปลงเทมเพลต:
INSERT INTO ` test ` SET ` first ` = " 123 " , ` second ` = " 456 "
?a*
- ตั้งค่าตัวยึดตำแหน่งจากอาร์เรย์แบบธรรมดา (หรือแบบเชื่อมโยง) โดยสร้างลำดับของค่า โดยที่ *
เป็นหนึ่งในประเภท:
i
(ตัวยึดจำนวนเต็ม)d
(ตัวยึดตำแหน่งลอย)s
(ตัวยึดประเภทสตริง)กฎสำหรับการแปลงและการ Escape จะเหมือนกับกฎสำหรับประเภทสเกลาร์เดี่ยวที่อธิบายไว้ข้างต้น ตัวอย่าง:
$ 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