這裏不僅會提高你的錯誤信息質量的方法,它會提高你處理你的結果集的方式。
$q["Orders"]="SELECT * FROM orders WHERE location = 'IN' ORDER BY orderNum DESC LIMIT 20";
$q["Inventory"]="SELECT * FRO inventory";
if(!$link=mysqli_connect("host","user","pass","db")){
echo "Failed to connect to MySQL: ",mysqli_connect_error();
}elseif(mysqli_multi_query($link,implode(';',$q))){
do{
$q_key=key($q); // current query's key name (Orders or Inventory)
if($result=mysqli_store_result($link)){ // if a result set... SELECTs do
while($row=mysqli_fetch_assoc($result)){ // if one or more rows, iterate all
$rows[$q_key][]=$row;
}
mysqli_free_result($result);
echo "<div><pre>"; // <pre> is for easier array reading
var_export($rows[$q_key]);
echo "</pre></div>";
}
} while(next($q) && mysqli_more_results($link) && mysqli_next_result($link));
}
if($mysqli_error=mysqli_error($link)){ // check & declare variable in same step to avoid duplicate func call
echo "<div style=\"color:red;\">Query Key = ",key($q),", Query = ",current($q),", Syntax Error = $mysqli_error</div>";
}
錯誤在第一個查詢: 如果你的第一個查詢試圖訪問不喜歡被提名的數據庫中的表:ordersXYZ
陣列$rows
將不存在,沒有var_export()
會發生,而你將看到這樣的響應:
查詢鍵=訂單,查詢= SELECT * FROM ordersXYZ WHERE位置= 'IN' ORDER BY ORDERNUM DESC LIMIT 20,語法錯誤=表 '[someDB] .ordersXYZ' 不存在
錯誤在第二個查詢: 如果你的第一個查詢是成功的,但你的第二個查詢試圖訪問像一個不存在的表:inventory2
$rows["Orders"]
將持有該行的數據,將是var_export()
「版,$row["Inventory"]
將不存在,你會看到這樣的響應:
查詢鍵=庫存,查詢= SELECT * FROM inventory2,語法錯誤=表 '[someDB] .inventory2' 不存在
個
沒有錯誤: 如果這兩個查詢是免費的錯誤,你$rows
陣列將充滿期望的數據和var_export()
「版,並不會有錯誤響應。查詢的數據保存在$rows
中,您可以從$rows["Orders"]
和$rows["Inventory"]
訪問您想要的內容。
注意事項:
您可能注意到,我在同一時間,使變量聲明和有條件的檢查,這使得代碼更幹。
由於我的方法在elseif
行上使用了帶分號的implode()
,請確保不要在查詢中添加尾隨分號。
這組查詢總是返回設置,因爲所有人都SELECT查詢,如果你有疑問的是affect_rows
,你會發現這個鏈接(https://stackoverflow.com/a/22469722/2943403)一些有用的信息的混合組合的結果。
mysqli_multi_query()
將在出現錯誤時立即停止運行查詢。如果您希望抓住「所有」錯誤,您會發現永遠不會有多於一個。
寫入OP的問題和解決方案中的條件性斷點是不可取的。雖然在其他情況下可以正確使用自定義斷點,但在這種情況下,斷點應位於do()
塊的while()
語句中。
返回零行不會導致錯誤信息的查詢 - 它只是不會在$rows
創建任何子陣,因爲while()
循環將不進入。
通過使用key()
函數,可以避免對每個結果集行中的列進行計數的OP的if/elseif
條件。這是更好的做法,因爲在某些情況下在每次迭代中運行條件可能會變得很昂貴。請注意,在迭代的每個do()
結束時,數組指針在$q
內部被提前。這是一個額外的技術,你不會在PHP手冊頁上找到;它允許key()
按預期工作。
而且,當然,<div><pre>var_export()...</pre></div>
行可以從您的工作代碼中刪除 - 這純粹是爲了演示。
如果您要在重複使用變量的此代碼塊之後運行更多查詢,請務必清除所有使用的變量,以便殘留數據不會發生干擾。例如$mysqli_error=null; // clear errors
& reset($q); // reset array pointer
。
你要謹慎,在你自己的判斷這有些含糊的警告:http://php.net/manual/en/mysqli.use-result.php:
一個不應使用mysqli_use_result()如果進行了大量的 客戶端處理的,因爲這會佔用服務器和 阻止其他線程更新從中獲取數據的所有數據表 。
最後和最重要出於安全考慮,不要公開展示查詢或查詢錯誤的信息 - 你不想險惡看到這樣的反饋。同樣重要的是,始終保護您的查詢免受注入攻擊。如果您的查詢包含用戶提供的數據,則在使用mysqli_multi_query()
之前,您需要過濾/清理數據。在用戶輸入問題時其實我很強烈的建議是從mysqli_multi_query()
移開,並請使用prepared statements或pdo爲你的數據庫交互的安全性更高的水平。
好評。這不會在第一個查詢中發現錯誤。 – David
當然,您需要檢查所有函數的返回值,即第一個查詢的mysqli_multi_query和mysqli_store_result,以及其餘所有函數的mysqli_next_result。 – rx80