ฐานข้อมูลที่ครบถ้วนสมบูรณ์จำนวนมากสนับสนุนแนวคิดของข้อความที่เตรียมไว้
งบที่เตรียมไว้มีอะไรบ้าง? ให้คิดว่ามันเป็นเทมเพลตที่คอมไพล์ของ SQL ที่คุณต้องการเรียกใช้ ซึ่งสามารถปรับแต่งได้โดยใช้พารามิเตอร์ตัวแปร ข้อความที่เตรียมไว้สามารถนำมาซึ่งประโยชน์หลักสองประการ:
แบบสอบถามจำเป็นต้องแยกวิเคราะห์ (หรือประมวลผลล่วงหน้า) เพียงครั้งเดียว แต่สามารถดำเนินการได้หลายครั้งด้วยพารามิเตอร์เดียวกันหรือต่างกัน เมื่อแบบสอบถามพร้อม ฐานข้อมูลจะวิเคราะห์ คอมไพล์ และปรับแผนสำหรับการดำเนินการค้นหาให้เหมาะสม กระบวนการนี้ใช้เวลานานกว่าสำหรับการสืบค้นที่ซับซ้อน และอาจทำให้แอปพลิเคชันของคุณช้าลงอย่างมาก หากจำเป็นต้องทำซ้ำการสืบค้นเดียวกันหลายครั้งด้วยพารามิเตอร์ที่แตกต่างกัน ด้วยการใช้คำสั่งที่เตรียมไว้ คุณสามารถหลีกเลี่ยงรอบการวิเคราะห์/คอมไพล์/การปรับให้เหมาะสมซ้ำๆ ได้ พูดง่ายๆ ก็คือ คำสั่งที่เตรียมไว้จะใช้ทรัพยากรน้อยลง ดังนั้นจึงทำงานได้เร็วขึ้น
พารามิเตอร์ที่ให้ไว้ในคำสั่งที่เตรียมไว้ไม่จำเป็นต้องอยู่ในเครื่องหมายคำพูด ไดรเวอร์จะจัดการสิ่งนี้โดยอัตโนมัติ หากแอปพลิเคชันของคุณใช้คำสั่งที่เตรียมไว้เท่านั้น คุณสามารถมั่นใจได้ว่าการแทรก SQL จะไม่เกิดขึ้น (อย่างไรก็ตาม หากส่วนอื่นๆ ของแบบสอบถามถูกสร้างขึ้นจากอินพุตที่ไม่ได้ใช้ Escape ก็จะยังคงมีความเสี่ยงที่จะมีการแทรก SQL)
ข้อความที่เตรียมไว้มีประโยชน์มากจนมีคุณลักษณะเดียวคือ PDO จะจำลองการประมวลผลเมื่อไดรเวอร์ไม่รองรับ เพื่อให้แน่ใจว่าแอปพลิเคชันสามารถใช้รูปแบบการเข้าถึงข้อมูลเดียวกัน ไม่ว่าฐานข้อมูลจะมีความสามารถดังกล่าวหรือไม่ก็ตาม
ตัวอย่างต่อไปนี้ดำเนินการแบบสอบถามแบบแทรกโดยแทนที่ตัวยึดที่มีชื่อที่สอดคล้องกันด้วยชื่อและค่า
<?php$stmt = $dbh->prepare("INSERT INTO REGISTRY (ชื่อ, ค่า) VALUES (:name, :value)");$stmt->bindParam(':name', $name);$stmt- >bindParam(':value', $value);//แทรกแถว $name = 'one';$value = 1;$stmt->execute();// แทรกแถวอื่นที่มีค่าต่างกัน $name = 'two';$value = 2;$stmt->execute();?>
ตัวอย่างต่อไปนี้ดำเนินการแบบสอบถามแบบแทรกโดยแทนที่ตัวยึดตำแหน่ง ? ด้วยชื่อและค่า
<?php$stmt = $dbh->prepare("INSERT INTO REGISTRY (ชื่อ, ค่า) ค่า (?, ?)");$stmt->bindParam(1, $name);$stmt->bindParam(2, $value);//แทรกแถว $name = 'one';$value = 1;$stmt->execute();// แทรกแถวอื่นที่มีค่าต่างกัน $name = 'two';$value = 2;$stmt->execute();?>
ตัวอย่างต่อไปนี้ได้รับข้อมูลตามค่าคีย์ในแบบฟอร์มที่ให้ไว้ อินพุตของผู้ใช้จะถูกอ้างอิงโดยอัตโนมัติ ดังนั้นจึงไม่มีอันตรายจากการโจมตีแบบแทรก SQL
<?php$stmt = $dbh->prepare("SELECT * FROM REGISTRY โดยที่ name = ?");if ($stmt->execute(array($_GET['name']))) { while ($row = $stmt->ดึงข้อมูล()) { print_r($row); }}?>
หากไดรเวอร์ฐานข้อมูลรองรับ แอปพลิเคชันยังสามารถผูกพารามิเตอร์เอาต์พุตและอินพุตได้ มักใช้เพื่อรับค่าจากขั้นตอนที่เก็บไว้ พารามิเตอร์เอาต์พุตมีความซับซ้อนในการใช้งานมากกว่าพารามิเตอร์อินพุตเล็กน้อย เนื่องจากเมื่อรวมพารามิเตอร์เอาต์พุต คุณต้องทราบความยาวของพารามิเตอร์ที่กำหนด หากค่าที่เชื่อมโยงกับพารามิเตอร์มากกว่าความยาวที่แนะนำ จะเกิดข้อผิดพลาดขึ้น
<?php$stmt = $dbh->prepare("CALL sp_returns_string(?)");$stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000); // เรียกโพรซีเดอร์ที่เก็บไว้ $stmt-> ดำเนินการ ();พิมพ์ "ขั้นตอนส่งคืน $return_valuen";?>
คุณยังสามารถระบุพารามิเตอร์ที่มีทั้งค่าอินพุตและเอาต์พุต โดยมีไวยากรณ์คล้ายกับพารามิเตอร์เอาต์พุต ในตัวอย่างถัดไป สตริง "hello" จะถูกส่งผ่านไปยัง Stored Procedure และเมื่อ Stored Procedure ส่งกลับ Hello จะถูกแทนที่ด้วยค่าที่ส่งกลับโดย Stored Procedure
<?php$stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)");$value = 'สวัสดี';$stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000 ); // เรียกโพรซีเดอร์ที่เก็บไว้ $stmt->execute();print "procedure return $valuen";?>
<?php$stmt = $dbh->prepare("SELECT * FROM REGISTRY โดยที่ชื่อ LIKE '%?%'");$stmt->execute(array($_GET['name']));// สัญลักษณ์ตัวยึดตำแหน่ง ต้องใช้ตลอดทั้งค่า $stmt = $dbh->prepare("SELECT * FROM REGISTRY โดยที่ชื่อ LIKE ?");$stmt->execute(array("%$_GET[ชื่อ]%"));?>