Русскоязычная документация находится тут
คุณสามารถดาวน์โหลดเป็นไฟล์เก็บถาวร โคลนจากไซต์นี้ หรือดาวน์โหลดผ่านผู้แต่ง (ลิงก์ไปยัง packagist.org):
composer require krugozor/database
krugozor/database คืออะไร ? krugozor/database เป็นไลบรารีคลาส PHP >= 8.0 สำหรับการทำงานที่ง่าย สะดวก รวดเร็วและปลอดภัยกับฐานข้อมูล MySql โดยใช้ส่วนขยาย PHP mysqli
ข้อเสียเปรียบหลักของไลบรารีทั้งหมดสำหรับการทำงานกับฐานข้อมูล mysql ใน PHP คือ:
int และ floatkrugozor/database เป็นคลาสสำหรับการทำงานกับ MySqlmysqli และ mysqli_result เพื่อสร้างวิธีการที่คุณต้องการใช้งานkrugozor/databaseWrapper ส่วนใหญ่สำหรับไดรเวอร์ฐานข้อมูลต่างๆ เป็นกลุ่มโค้ดที่ไม่มีประโยชน์และมีสถาปัตยกรรมที่น่าขยะแขยง ผู้เขียนไม่เข้าใจจุดประสงค์ในทางปฏิบัติของ 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 และแบบ doublebool TRUE ถูกแปลงเป็น int(1) , FALSE ถูกแปลงเป็น int(0)null ถูกแปลงเป็น int(0)double (ตัวยึดตำแหน่ง ?d )string และประเภท intbool 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