หลังจากครึ่งวันของการเล่นซอกับสิ่งนี้พบว่า PDO มีจุดบกพร่องที่ ...
-
//This would run as expected:
$pdo->exec("valid-stmt1; valid-stmt2;");
-
//This would error out, as expected:
$pdo->exec("non-sense; valid-stmt1;");
-
//Here is the bug:
$pdo->exec("valid-stmt1; non-sense; valid-stmt3;");
มันจะดำเนินการ"valid-stmt1;"
หยุด"non-sense;"
และไม่เกิดข้อผิดพลาด จะไม่เรียกใช้"valid-stmt3;"
คืนจริงและโกหกว่าทุกอย่างดำเนินไปด้วยดี
ฉันคาดหวังว่ามันจะผิดพลาด"non-sense;"
แต่ก็ไม่เกิดขึ้น
ที่นี่ฉันพบข้อมูลนี้:
แบบสอบถาม PDO ที่ไม่ถูกต้องไม่ส่งคืนข้อผิดพลาด
นี่คือจุดบกพร่อง:
https://bugs.php.net/bug.php?id=61613
ดังนั้นฉันจึงลองทำสิ่งนี้กับ mysqli และยังไม่พบคำตอบที่ชัดเจนเกี่ยวกับวิธีการทำงานดังนั้นฉันจึงคิดว่าจะทิ้งไว้ที่นี่สำหรับผู้ที่ต้องการใช้ ..
try{
// db connection
$mysqli = new mysqli("host", "user" , "password", "database");
if($mysqli->connect_errno){
throw new Exception("Connection Failed: [".$mysqli->connect_errno. "] : ".$mysqli->connect_error );
exit();
}
// read file.
// This file has multiple sql statements.
$file_sql = file_get_contents("filename.sql");
if($file_sql == "null" || empty($file_sql) || strlen($file_sql) <= 0){
throw new Exception("File is empty. I wont run it..");
}
//run the sql file contents through the mysqli's multi_query function.
// here is where it gets complicated...
// if the first query has errors, here is where you get it.
$sqlFileResult = $mysqli->multi_query($file_sql);
// this returns false only if there are errros on first sql statement, it doesn't care about the rest of the sql statements.
$sqlCount = 1;
if( $sqlFileResult == false ){
throw new Exception("File: '".$fullpath."' , Query#[".$sqlCount."], [".$mysqli->errno."]: '".$mysqli->error."' }");
}
// so handle the errors on the subsequent statements like this.
// while I have more results. This will start from the second sql statement. The first statement errors are thrown above on the $mysqli->multi_query("SQL"); line
while($mysqli->more_results()){
$sqlCount++;
// load the next result set into mysqli's active buffer. if this fails the $mysqli->error, $mysqli->errno will have appropriate error info.
if($mysqli->next_result() == false){
throw new Exception("File: '".$fullpath."' , Query#[".$sqlCount."], Error No: [".$mysqli->errno."]: '".$mysqli->error."' }");
}
}
}
catch(Exception $e){
echo $e->getMessage(). " <pre>".$e->getTraceAsString()."</pre>";
}