這不適用於 mysqlnd,並被標記為 wontfix(不予修復): https://bugs.php.net/bug.php?id=52561
(PHP 5, PHP 7, PHP 8)
mysqli::ping -- mysqli_ping — 向伺服器連線傳送 ping 指令,如果連線已斷線,則嘗試重新連線
此函式自 PHP 8.4.0 起已被 _棄用_。強烈建議不要依賴此函式。
物件導向風格
程序式風格
檢查與伺服器的連線是否正常運作。如果連線已斷線且全域選項 mysqli.reconnect 已啟用,則會嘗試自動重新連線。
注意事項:mysqlnd 驅動程式會忽略 php.ini 設定檔中的 mysqli.reconnect 設定,因此永遠不會嘗試自動重新連線。
此函式可供閒置較長時間的客戶端使用,以檢查伺服器是否已關閉連線,並在必要時重新連線。
如果啟用了 mysqli 錯誤報告 (MYSQLI_REPORT_ERROR
) 且請求的操作失敗,則會產生警告。此外,如果模式設定為 MYSQLI_REPORT_STRICT
,則會改為拋出 mysqli_sql_exception。
版本 | 說明 |
---|---|
8.4.0 | mysqli::ping() 和 mysqli_ping() 現已棄用。自 PHP 8.2.0 起,不再提供 `reconnect` 功能,因此此函式已過時。 |
範例 #1 mysqli::ping() 範例
物件導向風格
<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* 檢查連線 */
if ($mysqli->connect_errno) {
printf("連線失敗:%s\n", $mysqli->connect_error);
exit();
}
/* 檢查伺服器是否正在運行 */
if ($mysqli->ping()) {
printf ("我們的連線正常!\n");
} else {
printf ("錯誤:%s\n", $mysqli->error);
}
/* 關閉連線 */
$mysqli->close();
?>
程序式風格
<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");
/* 檢查連線 */
if (mysqli_connect_errno()) {
printf("連線失敗: %s\n", mysqli_connect_error());
exit();
}
/* 檢查伺服器是否存活 */
if (mysqli_ping($link)) {
printf ("連線正常!\n");
} else {
printf ("錯誤: %s\n", mysqli_error($link));
}
/* 關閉連線 */
mysqli_close($link);
?>
以上範例會輸出
Our connection is ok!
這不適用於 mysqlnd,並被標記為 wontfix(不予修復): https://bugs.php.net/bug.php?id=52561
正如 jay at grooveshark dot com 非常有幫助地指出,越來越成為標準的 mysqlnd 驅動程式不遵守重新連線指令。如果您有一個資料庫包裝器類別(希望您有),您可以實現您自己的 ping() 版本,例如
<?php
class db extends mysqli
{
private $db_host;
private $db_user;
private $db_pass;
private $db_name;
private $persistent;
public function __construct($db_host, $db_user, $db_pass, $db_name, $persistent = true)
{
$this->db_host = $db_host;
$this->db_user = $db_user;
$this->db_pass = $db_pass;
$this->db_name = $db_name;
$this->persistent = $persistent;
parent::init();
parent::options(MYSQLI_OPT_CONNECT_TIMEOUT, 1);
@parent::real_connect(($this->persistent ? 'p:' : '') . $this->db_host, $this->db_user, $this->db_pass, $this->db_name);
if ($this->connect_errno)
die("All DB servers down!\n");
}
public function ping()
{
@parent::query('SELECT LAST_INSERT_ID()');
if ($this->errno == 2006)
$this->__construct($this->db_host, $this->db_user, $this->db_pass, $this->db_name, $this->persistent);
}
...
}
$db = new db(DB_HOST, DB_USER, DB_PASS, DB_NAME);
// Some code that potentially takes a really long time to execute goes here
// Ping for safety to try to gracefully reconnect
$db->ping();
// Now we should be able to run queries again
$db->query('SELECT LAST_INSERT_ID()');
?>
如果您願意,您甚至可以將 "$this->ping();" 放在 db::query() 的頂部,以避免任何明確的重新連線呼叫,但我不建議這樣做,因為在每次執行真正的預期查詢之前執行廉價的 "SELECT LAST_INSERT_ID()" 查詢會產生(輕微的)額外開銷。可能有比 "SELECT LAST_INSERT_ID()" 更廉價的查詢可以執行,但這是第一個想到的,而且對於大多數用途來說已經夠廉價了,因為您不應該頻繁地呼叫 ping()。
在 Debian PHP 套件中,關於 mysqli.reconnect 選項的行為預設設定為關閉。所以我建議更新關於 mysqli.reconnect 選項建議的第一行描述。(實務注意事項 ;))