PHP มี API ที่แตกต่างกันสามตัวเพื่อเชื่อมต่อกับ MySQL เหล่านี้คือmysql
(ถูกลบออกจาก PHP 7) mysqli
, และPDO
ส่วนขยาย
mysql_*
ฟังก์ชั่นที่ใช้ในการเป็นที่นิยมมาก แต่การใช้ของพวกเขาจะไม่ได้รับการสนับสนุนอีกต่อไป ทีมเอกสารกำลังพูดคุยเกี่ยวกับสถานการณ์ความปลอดภัยของฐานข้อมูลและให้ความรู้แก่ผู้ใช้ในการย้ายออกจากส่วนขยาย ext / mysql ที่ใช้กันทั่วไปเป็นส่วนหนึ่งของสิ่งนี้ (ตรวจสอบphp.internals: deprecating ext / mysql )
และทีมพัฒนา PHP ต่อมาได้ดำเนินการตัดสินใจที่จะสร้างE_DEPRECATED
ข้อผิดพลาดเมื่อผู้ใช้เชื่อมต่อกับ MySQL ไม่ว่าจะผ่านmysql_connect()
, หรือฟังก์ชั่นการเชื่อมต่อโดยปริยายที่สร้างขึ้นในmysql_pconnect()
ext/mysql
ext/mysql
ถูกเลิกใช้อย่างเป็นทางการตั้งแต่ PHP 5.5และถูกลบออกเมื่อ PHP 77
เห็นกล่องสีแดง?
เมื่อใดก็ตามที่คุณไป mysql_*
หน้าคู่มือการใช้งานคุณจะเห็นกล่องสีแดงอธิบายว่าไม่ควรใช้อีกต่อไป
ทำไม
การย้ายออกไปext/mysql
ไม่เพียง แต่เกี่ยวกับความปลอดภัยเท่านั้น แต่ยังเกี่ยวกับการเข้าถึงคุณลักษณะทั้งหมดของฐานข้อมูล MySQL ด้วย
ext/mysql
สร้างขึ้นสำหรับMySQL 3.23และมีการเพิ่มเติมเพียงเล็กน้อยตั้งแต่นั้นมาในขณะที่ส่วนใหญ่รักษาความเข้ากันได้กับเวอร์ชั่นเก่านี้ซึ่งทำให้รหัสยากต่อการบำรุงรักษา คุณสมบัติที่ขาดหายไปซึ่งไม่รองรับโดยext/mysql
รวม: ( จากคู่มือ PHP )
เหตุผลที่ไม่ใช้mysql_*
ฟังก์ชัน :
- ไม่ได้อยู่ภายใต้การพัฒนาที่ใช้งานอยู่
- ลบออกจาก PHP 7
- ขาดอินเตอร์เฟส OO
- ไม่รองรับข้อความค้นหาที่ไม่ปิดกั้นและไม่ตรงกัน
- ไม่รองรับข้อความที่เตรียมไว้หรือ ข้อความค้นหาที่กำหนดพารามิเตอร์
- ไม่รองรับขั้นตอนการจัดเก็บ
- ไม่รองรับคำสั่งหลายรายการ
- ไม่รองรับธุรกรรม
- ไม่รองรับฟังก์ชั่นทั้งหมดใน MySQL 5.1
จุดดังกล่าวมาจากคำตอบของเควนติน
การขาดการสนับสนุนงบที่เตรียมไว้มีความสำคัญอย่างยิ่งเนื่องจากมีวิธีการที่ชัดเจนและผิดพลาดน้อยกว่าในการหลบหนีและการอ้างถึงข้อมูลภายนอกมากกว่าการเรียกใช้ด้วยตนเองด้วยการเรียกฟังก์ชันที่แยกต่างหาก
ดูการเปรียบเทียบของนามสกุล SQL
ไม่แสดงคำเตือนการคัดค้าน
ในขณะที่รหัสกำลังถูกแปลงเป็นMySQLi
/ PDO
คุณE_DEPRECATED
สามารถระงับข้อผิดพลาดได้โดยการตั้งค่าerror_reporting
ในphp.iniเพื่อยกเว้นE_DEPRECATED:
error_reporting = E_ALL ^ E_DEPRECATED
โปรดทราบว่านี่จะซ่อนคำเตือนการคัดค้านอื่น ๆซึ่งอาจเป็นสิ่งอื่นนอกเหนือจาก MySQL ( จากคู่มือ PHP )
บทความPDO กับ MySQLi: คุณควรใช้แบบไหน โดยDejan Marjanovićจะช่วยให้คุณเลือก
และวิธีที่ดีกว่าคือPDO
ตอนนี้ฉันกำลังเขียนPDO
บทแนะนำอย่างง่าย
บทช่วยสอน PDO ที่ง่ายและสั้น
คำถามที่ถามเป็นครั้งแรกในใจของฉันได้รับสิ่งที่ PDO` คือ `?
A. “ PDO - PHP Data Objects - เป็นเลเยอร์การเข้าถึงฐานข้อมูลที่ให้วิธีการเข้าถึงฐานข้อมูลที่หลากหลายอย่างสม่ำเสมอ”
กำลังเชื่อมต่อกับ MySQL
ด้วยmysql_*
ฟังก์ชั่นหรือเราสามารถพูดได้แบบเก่า (เลิกใช้แล้วใน PHP 5.5 ขึ้นไป)
$link = mysql_connect('localhost', 'user', 'pass');
mysql_select_db('testdb', $link);
mysql_set_charset('UTF-8', $link);
ด้วยPDO
: สิ่งที่คุณต้องทำคือสร้างPDO
วัตถุใหม่ นวกรรมิกยอมรับพารามิเตอร์สำหรับการระบุแหล่งที่มาของฐานข้อมูลPDO
ของคอนสตรัคส่วนใหญ่ใช้พารามิเตอร์สี่ซึ่งเป็นDSN
(ชื่อแหล่งข้อมูล) และเลือกusername
,password
.
ที่นี่ฉันคิดว่าคุณคุ้นเคยกับทุกคนยกเว้นDSN
; PDO
นี้คือในใหม่ A DSN
นั้นเป็นสตริงของตัวเลือกที่บอกว่าPDO
จะใช้ไดรเวอร์ใดและรายละเอียดการเชื่อมต่อ สำหรับการอ้างอิงต่อไปตรวจสอบPDO MySQL DSN
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8', 'username', 'password');
หมายเหตุ:คุณสามารถใช้งานcharset=UTF-8
ได้ แต่บางครั้งก็ทำให้เกิดข้อผิดพลาดดังนั้นจึงควรใช้งานutf8
แต่บางครั้งก็ทำให้เกิดข้อผิดพลาดดังนั้นจึงเป็นเรื่องที่ดีที่จะใช้
หากมีข้อผิดพลาดในการเชื่อมต่อมันจะโยนPDOException
วัตถุที่สามารถจับได้Exception
ต่อไป
อ่านดี : การเชื่อมต่อและการจัดการการเชื่อมต่อ¶
คุณยังสามารถส่งผ่านตัวเลือกไดร์เวอร์หลายตัวเป็นอาร์เรย์ไปยังพารามิเตอร์ที่สี่ ฉันขอแนะนำให้ส่งพารามิเตอร์ที่ทำให้PDO
อยู่ในโหมดยกเว้น เนื่องจากPDO
ไดรเวอร์บางตัวไม่รองรับคำสั่งพื้นฐานที่เตรียมไว้ดังนั้นPDO
ทำการจำลองการเตรียมการ นอกจากนี้ยังช่วยให้คุณเปิดใช้งานการจำลองนี้ด้วยตนเอง false
เมื่อต้องการใช้ด้านเซิร์ฟเวอร์พื้นเมืองเตรียมงบคุณควรกำหนดอย่างชัดเจน
อีกวิธีหนึ่งคือปิดการเตรียมการจำลองซึ่งเปิดใช้งานในMySQL
ไดรเวอร์ตามค่าเริ่มต้น แต่ควรปิดการจำลองการเตรียมใช้งานPDO
อย่างปลอดภัย
ฉันจะอธิบายในภายหลังว่าทำไมการเตรียมการจำลองจึงควรปิด เพื่อหาเหตุผลโปรดตรวจสอบโพสต์นี้นี้
มันสามารถใช้งานได้เฉพาะถ้าคุณใช้รุ่นเก่า MySQL
ซึ่งฉันไม่แนะนำ
ด้านล่างเป็นตัวอย่างของวิธีที่คุณสามารถทำได้:
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8',
'username',
'password',
array(PDO::ATTR_EMULATE_PREPARES => false,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
เราสามารถตั้งค่าแอตทริบิวต์หลังจากการก่อสร้าง PDO ได้หรือไม่?
ใช่เราสามารถกำหนดคุณลักษณะบางอย่างหลังจากการสร้าง PDO ด้วยsetAttribute
วิธีการ:
$db = new PDO('mysql:host=localhost;dbname=testdb;charset=UTF-8',
'username',
'password');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
การจัดการข้อผิดพลาด
จัดการข้อผิดพลาดเป็นเรื่องง่ายในกว่าPDO
mysql_*
วิธีปฏิบัติทั่วไปเมื่อใช้mysql_*
คือ:
//Connected to MySQL
$result = mysql_query("SELECT * FROM table", $link) or die(mysql_error($link));
OR die()
ไม่ใช่วิธีที่ดีในการจัดการข้อผิดพลาดเนื่องจากเราไม่สามารถจัดการกับสิ่งที่เกิดdie
ขึ้นได้ มันจะจบสคริปต์ทันทีและจากนั้นสะท้อนข้อผิดพลาดไปที่หน้าจอซึ่งโดยปกติคุณไม่ต้องการแสดงให้ผู้ใช้ปลายทางของคุณทราบ อีกทางหนึ่งค่าส่งคืนของmysql_*
ฟังก์ชันมักใช้ร่วมกับmysql_error ()เพื่อจัดการข้อผิดพลาด
PDO
เสนอทางออกที่ดีกว่า: ข้อยกเว้น สิ่งใดที่เราทำกับPDO
ควรจะห่อในtry
- catch
บล็อก เราสามารถบังคับให้PDO
เข้าสู่โหมดข้อผิดพลาดหนึ่งในสามโหมดโดยการตั้งค่าแอตทริบิวต์โหมดข้อผิดพลาด โหมดการจัดการข้อผิดพลาดสามโหมดอยู่ด้านล่าง
PDO::ERRMODE_SILENT
. มันเป็นเพียงการตั้งรหัสข้อผิดพลาดและทำหน้าที่เหมือนกับmysql_*
ที่คุณต้องตรวจสอบผลการค้นหาแต่ละครั้งแล้วดูที่$db->errorInfo();
รายละเอียดข้อผิดพลาด
PDO::ERRMODE_WARNING
E_WARNING
ยก (คำเตือนรันไทม์ (ข้อผิดพลาดที่ไม่ร้ายแรง) การดำเนินการของสคริปต์จะไม่หยุด)
PDO::ERRMODE_EXCEPTION
: โยนข้อยกเว้น เพราะแสดงถึงข้อผิดพลาดที่เกิดจาก PDO คุณไม่ควรโยนPDOException
จากรหัสของคุณเอง ดูข้อยกเว้นสำหรับข้อมูลเพิ่มเติมเกี่ยวกับข้อยกเว้นใน PHP มันทำหน้าที่เหมือนอย่างมากor die(mysql_error());
เมื่อไม่ถูกจับ แต่แตกต่างจากor die()
ที่PDOException
สามารถจับและจัดการได้อย่างสง่างามหากคุณเลือกที่จะทำ
อ่านดี :
ชอบ:
$stmt->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_SILENT );
$stmt->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING );
$stmt->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
และคุณสามารถห่อมันได้try
- catch
เช่นด้านล่าง:
try {
//Connect as appropriate as above
$db->query('hi'); //Invalid query!
}
catch (PDOException $ex) {
echo "An Error occured!"; //User friendly message/message you want to show to user
some_logging_function($ex->getMessage());
}
คุณไม่ต้องจัดการกับtry
- catch
ตอนนี้ คุณสามารถจับมันที่เหมาะสมเวลาใด ๆ แต่ผมขอแนะนำให้คุณใช้-try
catch
นอกจากนี้มันอาจจะสมเหตุสมผลมากกว่าที่จะจับมันที่นอกฟังก์ชั่นที่เรียกใช้PDO
สิ่งต่าง ๆ :
function data_fun($db) {
$stmt = $db->query("SELECT * FROM table");
return $stmt->fetchAll(PDO::FETCH_ASSOC);
}
//Then later
try {
data_fun($db);
}
catch(PDOException $ex) {
//Here you can handle error and show message/perform action you want.
}
นอกจากนี้คุณสามารถจัดการโดย or die()
หรือเราสามารถพูดชอบmysql_*
แต่มันจะแตกต่างกันจริงๆ คุณสามารถซ่อนข้อความแสดงข้อผิดพลาดที่เป็นอันตรายในการผลิตโดยการเปิดdisplay_errors off
และเพียงแค่อ่านบันทึกข้อผิดพลาดของคุณ
ตอนนี้หลังจากที่ได้อ่านทุกสิ่งข้างต้นคุณอาจจะคิด: ห่าคือว่าเมื่อผมแค่อยากจะเริ่มต้นพิงง่ายSELECT
, INSERT
,UPDATE
หรือDELETE
งบ? ไม่ต้องกังวลไปเลย:
การเลือกข้อมูล
ดังนั้นสิ่งที่คุณกำลังทำ mysql_*
คือ:
<?php
$result = mysql_query('SELECT * from table') or die(mysql_error());
$num_rows = mysql_num_rows($result);
while($row = mysql_fetch_assoc($result)) {
echo $row['field1'];
}
ตอนนี้ใน PDO
คุณสามารถทำสิ่งนี้เช่น:
<?php
$stmt = $db->query('SELECT * FROM table');
while($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
echo $row['field1'];
}
หรือ
<?php
$stmt = $db->query('SELECT * FROM table');
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
//Use $results
หมายเหตุ : หากคุณใช้วิธีการดังต่อไปนี้ ( query()
) วิธีการนี้จะคืนค่า aPDOStatement
วัตถุ ดังนั้นหากคุณต้องการดึงผลลัพธ์ให้ใช้เหมือนด้านบน
<?php
foreach($db->query('SELECT * FROM table') as $row) {
echo $row['field1'];
}
ใน PDO Data จะได้รับผ่านทาง ->fetch()
วิธีการจัดการรายการบัญชีของคุณ ก่อนที่จะเรียกการดึงข้อมูลวิธีที่ดีที่สุดจะบอก PDO ว่าคุณต้องการดึงข้อมูลอย่างไร ในส่วนด้านล่างนี้ฉันอธิบายเรื่องนี้
ดึงข้อมูลโหมด
สังเกตการใช้งานPDO::FETCH_ASSOC
ในfetch()
และfetchAll()
รหัสด้านบน สิ่งนี้จะบอกPDO
ให้คืนค่าแถวเป็นอาเรย์แบบเชื่อมโยงที่มีชื่อฟิลด์เป็นกุญแจ มีโหมดการดึงข้อมูลอื่น ๆ อีกมากมายเช่นกันซึ่งฉันจะอธิบายทีละคน
ก่อนอื่นฉันอธิบายวิธีเลือกโหมดดึงข้อมูล:
$stmt->fetch(PDO::FETCH_ASSOC)
fetch()
ในข้างต้นผมได้ใช้ คุณยังสามารถใช้:
ตอนนี้ฉันมาโหมดดึงข้อมูล:
PDO::FETCH_ASSOC
: ส่งคืนอาร์เรย์ที่จัดทำดัชนีโดยชื่อคอลัมน์ตามที่ส่งคืนในชุดผลลัพธ์ของคุณ
PDO::FETCH_BOTH
(ค่าเริ่มต้น): ส่งกลับอาร์เรย์ที่ทำดัชนีโดยทั้งชื่อคอลัมน์และหมายเลขคอลัมน์ 0 ดัชนีที่ส่งคืนในชุดผลลัพธ์ของคุณ
มีตัวเลือกมากขึ้น! อ่านเกี่ยวกับพวกเขาทั้งหมดในPDOStatement
เอกสารการดึงข้อมูล .
รับจำนวนแถว :
แทนที่จะใช้mysql_num_rows
เพื่อรับจำนวนแถวที่ส่งคืนคุณสามารถรับPDOStatement
และทำrowCount()
เช่น:
<?php
$stmt = $db->query('SELECT * FROM table');
$row_count = $stmt->rowCount();
echo $row_count.' rows selected';
รับ ID ที่แทรกล่าสุด
<?php
$result = $db->exec("INSERT INTO table(firstname, lastname) VAULES('John', 'Doe')");
$insertId = $db->lastInsertId();
แทรกและอัปเดตหรือลบคำสั่ง
สิ่งที่เรากำลังทำอยู่mysql_*
คือ:
<?php
$results = mysql_query("UPDATE table SET field='value'") or die(mysql_error());
echo mysql_affected_rows($result);
และใน pdo สิ่งเดียวกันนี้สามารถทำได้โดย:
<?php
$affected_rows = $db->exec("UPDATE table SET field='value'");
echo $affected_rows;
ในแบบสอบถามข้างต้นPDO::exec
ดำเนินการคำสั่ง SQL และส่งกลับจำนวนแถวที่ได้รับผลกระทบ
การแทรกและการลบจะถูกครอบคลุมในภายหลัง
วิธีการข้างต้นมีประโยชน์เฉพาะเมื่อคุณไม่ได้ใช้ตัวแปรในแบบสอบถาม แต่เมื่อคุณต้องการใช้ตัวแปรในแบบสอบถามไม่เคยลองเหมือนด้านบนและมี คำสั่งที่เตรียมไว้หรือคำสั่งที่กำหนดพารามิเตอร์แล้ว
งบเตรียม
ถามแถลงการณ์ที่เตรียมไว้คืออะไรและทำไมฉันถึงต้องการมัน
A.คำสั่งที่เตรียมไว้เป็นคำสั่ง SQL ที่รวบรวมไว้ล่วงหน้าซึ่งสามารถดำเนินการได้หลายครั้งโดยส่งข้อมูลไปยังเซิร์ฟเวอร์เท่านั้น
เวิร์กโฟลว์ทั่วไปของการใช้คำสั่งที่เตรียมไว้มีดังต่อไปนี้ ( อ้างอิงจาก Wikipedia สามจุด 3 จุด ):
จัดเตรียม : เท็มเพลตคำสั่งถูกสร้างโดยแอปพลิเคชันและส่งไปยังระบบจัดการฐานข้อมูล (DBMS) ค่าบางอย่างถูกทิ้งไว้โดยไม่ระบุซึ่งเรียกว่าพารามิเตอร์ตัวยึดตำแหน่งหรือตัวแปรผูก (ติดป้าย?
ด้านล่าง):
INSERT INTO PRODUCT (name, price) VALUES (?, ?)
DBMS แยกวิเคราะห์รวบรวมและดำเนินการปรับให้เหมาะสมแบบสอบถามในแม่แบบคำสั่งและเก็บผลลัพธ์โดยไม่ต้องดำเนินการ
- ดำเนินการ : ในภายหลังแอปพลิเคชั่นจะส่งค่า (หรือผูก) สำหรับพารามิเตอร์และ DBMS เรียกใช้คำสั่ง (อาจส่งคืนผลลัพธ์) แอปพลิเคชันอาจดำเนินการคำสั่งหลาย ๆ ครั้งตามที่ต้องการด้วยค่าที่ต่างกัน ในตัวอย่างนี้อาจให้ 'Bread' สำหรับพารามิเตอร์แรกและพารามิเตอร์
1.00
ที่สอง
คุณสามารถใช้คำสั่งที่เตรียมไว้โดยรวมตัวยึดตำแหน่งใน SQL ของคุณ โดยทั่วไปจะมีสามรายการที่ไม่มีตัวยึดตำแหน่ง (อย่าลองใช้ด้วยตัวแปรด้านบน) กับอันที่ไม่มีตัวยึดและอีกอันที่มีตัวยึดที่ตั้งชื่อไว้
ถามดังนั้นตอนนี้ตัวยึดตำแหน่งชื่ออะไรและฉันจะใช้ได้อย่างไร
A.ตัวยึดที่ระบุชื่อ ใช้ชื่อที่สื่อความหมายนำหน้าด้วยโคลอนแทนที่จะเป็นเครื่องหมายคำถาม เราไม่สนใจเกี่ยวกับตำแหน่ง / คำสั่งของมูลค่าในเจ้าของชื่อ:
$stmt->bindParam(':bla', $bla);
bindParam(parameter,variable,data_type,length,driver_options)
นอกจากนี้คุณยังสามารถผูกโดยใช้อาร์เรย์ดำเนินการเช่นกัน:
<?php
$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
$stmt->execute(array(':name' => $name, ':id' => $id));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
อีกคุณสมบัติที่ดีสำหรับOOP
เพื่อนคือชื่อตัวแทนมีความสามารถในการแทรกวัตถุลงในฐานข้อมูลของคุณโดยตรงโดยสมมติว่าคุณสมบัติตรงกับเขตข้อมูลที่มีชื่อ ตัวอย่างเช่น:
class person {
public $name;
public $add;
function __construct($a,$b) {
$this->name = $a;
$this->add = $b;
}
}
$demo = new person('john','29 bla district');
$stmt = $db->prepare("INSERT INTO table (name, add) value (:name, :add)");
$stmt->execute((array)$demo);
ถามดังนั้นตอนนี้ตัวยึดตำแหน่งที่ไม่มีชื่อคืออะไรและฉันจะใช้ได้อย่างไร
A.มีตัวอย่าง:
<?php
$stmt = $db->prepare("INSERT INTO folks (name, add) values (?, ?)");
$stmt->bindValue(1, $name, PDO::PARAM_STR);
$stmt->bindValue(2, $add, PDO::PARAM_STR);
$stmt->execute();
และ
$stmt = $db->prepare("INSERT INTO folks (name, add) values (?, ?)");
$stmt->execute(array('john', '29 bla district'));
ในด้านบนคุณสามารถเห็นสิ่งเหล่านั้น?
แทนชื่อเช่นในตัวยึดตำแหน่ง ในตัวอย่างแรกเรากำหนดตัวแปรให้กับตัวยึดตำแหน่งต่างๆ ( $stmt->bindValue(1, $name, PDO::PARAM_STR);
) จากนั้นเรากำหนดค่าให้กับตัวแทนเหล่านั้นและดำเนินการคำสั่ง ในตัวอย่างที่สององค์ประกอบแถวแรกที่ไปครั้งแรกและครั้งที่สองที่สอง?
?
หมายเหตุ : ในตัวยึดตำแหน่งที่ไม่มีชื่อเราจะต้องดูแลลำดับที่เหมาะสมขององค์ประกอบในอาร์เรย์ที่เรากำลังส่งผ่านไปยังPDOStatement::execute()
วิธีการ
SELECT
, INSERT
, UPDATE
, DELETE
จัดทำคำสั่ง
SELECT
:
$stmt = $db->prepare("SELECT * FROM table WHERE id=:id AND name=:name");
$stmt->execute(array(':name' => $name, ':id' => $id));
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
INSERT
:
$stmt = $db->prepare("INSERT INTO table(field1,field2) VALUES(:field1,:field2)");
$stmt->execute(array(':field1' => $field1, ':field2' => $field2));
$affected_rows = $stmt->rowCount();
DELETE
:
$stmt = $db->prepare("DELETE FROM table WHERE id=:id");
$stmt->bindValue(':id', $id, PDO::PARAM_STR);
$stmt->execute();
$affected_rows = $stmt->rowCount();
UPDATE
:
$stmt = $db->prepare("UPDATE table SET name=? WHERE id=?");
$stmt->execute(array($name, $id));
$affected_rows = $stmt->rowCount();
บันทึก:
อย่างไรก็ตามPDO
และ / หรือMySQLi
ไม่ปลอดภัยอย่างสมบูรณ์ ตรวจสอบคำตอบPDO มีการจัดทำงบอย่างเพียงพอเพื่อป้องกันการฉีด SQL หรือไม่? โดยircmaxell นอกจากนี้ฉันกำลังอ้างอิงบางส่วนจากคำตอบของเขา:
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$pdo->query('SET NAMES GBK');
$stmt = $pdo->prepare("SELECT * FROM test WHERE name = ? LIMIT 1");
$stmt->execute(array(chr(0xbf) . chr(0x27) . " OR 1=1 /*"));