我正在處理將JobName列定義爲UNIQUE的MySQL表。如果有人試圖使用已存在於數據庫中的JobName將新Job保存到數據庫,則MySQL將引發警告。我可以使用PHP檢測並處理MySQL警告嗎?
我想能夠檢測這個警告,就像一個錯誤,在我的PHP腳本,並用它妥善處理。理想情況下,我想知道MySQL拋出了什麼樣的警告,以便我可以分支代碼來處理它。
這可能嗎?如果沒有,是因爲MySQL沒有這個能力,PHP沒有這個能力,或者兩者兼而有之?
我正在處理將JobName列定義爲UNIQUE的MySQL表。如果有人試圖使用已存在於數據庫中的JobName將新Job保存到數據庫,則MySQL將引發警告。我可以使用PHP檢測並處理MySQL警告嗎?
我想能夠檢測這個警告,就像一個錯誤,在我的PHP腳本,並用它妥善處理。理想情況下,我想知道MySQL拋出了什麼樣的警告,以便我可以分支代碼來處理它。
這可能嗎?如果沒有,是因爲MySQL沒有這個能力,PHP沒有這個能力,或者兩者兼而有之?
的警告是「標記」,以PHP本身就需要改變在MySQL/MySQLi驅動程序,這顯然超出了這個問題的範圍。相反,你將不得不基本檢查您使數據庫的警告在每次查詢:
$warningCountResult = mysql_query("SELECT @@warning_count");
if ($warningCountResult) {
$warningCount = mysql_fetch_row($warningCountResult);
if ($warningCount[0] > 0) {
//Have warnings
$warningDetailResult = mysql_query("SHOW WARNINGS");
if ($warningDetailResult) {
while ($warning = mysql_fetch_assoc(warningDetailResult) {
//Process it
}
}
}//Else no warnings
}
顯然,這將是可怕昂貴適用EN-質量,所以你可能需要仔細想想,當以及如何產生警告(這可能導致您重構以消除它們)。
僅供參考,MySQL SHOW WARNINGS
當然,你可以用的SELECT @@warning_count
,這將節省您每次執行一個查詢的初始查詢免除,但我把它的迂腐完整性。
首先,您應該turn warnings off以便您的訪客不會看到您的MySQL錯誤。其次,當你打電話給mysql_query()
時,你應該檢查它是否返回錯誤。如果確實如此,請撥打mysql_errno()
以查明問題所在。將返回的編號與this page上的錯誤代碼相匹配。
它看起來這是你要找的錯誤編號:
Error: 1169 SQLSTATE: 23000 (ER_DUP_UNIQUE)
Message: Can't write, because of unique constraint, to table '%s'
如果我沒有記錯他詢問的警告,而不是錯誤。警告仍然允許查詢通過,因此`mysql_query`不會返回`false`。請參閱iAn對PHP有限警告支持的回答。 – Andrew 2013-12-07 20:36:09
更新,刪除有關錯誤號的功能,我現在認識到沒有在您的情況適用的東西...
一件事在MySQL警惕的爲UPDATE
聲明:mysqli_affected_rows()
將返回零,即使WHERE
子句匹配的行,但SET
條款實際上並沒有改變數據值。我只提到這一點,因爲這種行爲導致了我曾經看到的一個系統中的錯誤 - 程序員使用該返回值在更新後檢查錯誤,假設零表示發生了一些錯誤。這只是表示用戶在單擊更新按鈕之前沒有更改任何現有值。
所以我想用mysqli_affected_rows()
也不能依靠找到這樣的警告,除非你有像表中的update_time
列這樣的東西,總是會被分配一個新的時間戳值更新時。這種解決方法似乎有點kludgey雖然。
取決於什麼(如果有的話),你正在使用的框架,我建議你做一個查詢,以檢查作業名自己,並與驗證的表格的其餘部分創建正確的信息給用戶。
根據jobnames的數量,你可以在名稱發送到包含形式和使用JavaScript來告訴使用其所持的看法。
如果這對你沒有意義,那麼總結我的觀點是這樣的:不要設計你的程序和/或用戶試圖做非法的事情,並在他們做和處理它時捕捉錯誤。設計你的系統不會造成錯誤會更好,恕我直言。保持錯誤實際的錯誤:)
您可以檢測使用的mysqli語句錯誤沒有唯一鍵衝突。 mysqli語句返回錯誤1062,即ER_DUP_ENTRY。您可以查找錯誤1062並打印適當的錯誤消息。如果你想打印你的列(jobName)也作爲你的錯誤信息的一部分,那麼你應該解析語句錯誤字符串。
if($stmt = $mysqli->prepare($sql)){ $stmt->bind_param("sss", $name, $identKey, $domain); $stmt->execute(); if($mysqli->affected_rows != 1) { //This will return errorno 1062 trigger_error('mysql error >> '.$stmt->errno .'::' .$stmt->error, E_USER_ERROR); exit(1); } $stmt->close(); } else { trigger_error('mysql error >> '. $mysqli->errno.'::'.$mysqli->error,E_USER_ERROR); }
有可能得到警告,並且以比mysql更高效的方式使用mysqli。
這裏使用的是人工page建議在php.net的財產mysqli-> WARNING_COUNT代碼:上抑制警告
$mysqli->query($query);
if ($mysqli->warning_count) {
if ($result = $mysqli->query("SHOW WARNINGS")) {
$row = $result->fetch_row();
printf("%s (%d): %s\n", $row[0], $row[1], $row[2]);
$result->close();
}
}
注:一般來說,它是不以防止警告是個好主意顯示,因爲你可能會錯過重要的東西。如果你絕對必須隱藏某種原因警告,可以放置一個@
標誌在聲明前做一個單獨的基礎上。這樣,您不必關閉所有警告報告,並可以將其限制爲特定實例。
例子:
// this suppresses warnings that might result if there is no field titled "field" in the result
$field_value = @mysql_result($result, 0, "field");
這聽起來像用戶希望能夠捕獲錯誤,不surpress它。 – pgreen2 2012-11-29 04:42:21
ini_set('mysql.trace_mode', 1)
可能是你在找什麼。
的PHP錯誤然後可以用自定義的PHP錯誤處理程序處理,但你也可以只是關閉顯示PHP錯誤,因爲它們通常被記錄到日誌文件(取決於你的PHP配置)。
或者使用具有warning_count屬性的MySQLi驅動程序。 http://php.net/manual/en/mysqli.warning-count.php – 2011-10-19 12:33:59