2024 年日本 PHP 研討會

mysqli::ping

mysqli_ping

(PHP 5, PHP 7, PHP 8)

mysqli::ping -- mysqli_ping向伺服器連線傳送 ping 指令,如果連線已斷線,則嘗試重新連線

警告

此函式自 PHP 8.4.0 起已被 _棄用_。強烈建議不要依賴此函式。

說明

物件導向風格

#[\Deprecated]
public mysqli::ping(): bool

程序式風格

#[\Deprecated]
mysqli_ping(mysqli $mysql): bool

檢查與伺服器的連線是否正常運作。如果連線已斷線且全域選項 mysqli.reconnect 已啟用,則會嘗試自動重新連線。

注意事項mysqlnd 驅動程式會忽略 php.ini 設定檔中的 mysqli.reconnect 設定,因此永遠不會嘗試自動重新連線。

此函式可供閒置較長時間的客戶端使用,以檢查伺服器是否已關閉連線,並在必要時重新連線。

參數

mysql

僅限程序式風格:由 mysqli_connect()mysqli_init() 返回的 mysqli 物件

返回值

成功時返回 true,失敗時返回 false

錯誤/例外

如果啟用了 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!
新增註解

使用者貢獻的註解 3 則註解

jay at grooveshark dot com
10 年前
這不適用於 mysqlnd,並被標記為 wontfix(不予修復): https://bugs.php.net/bug.php?id=52561
root at jusme dot org
9 年前
正如 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()。
snooops84 at googlemail dot com
9 年前
在 Debian PHP 套件中,關於 mysqli.reconnect 選項的行為預設設定為關閉。所以我建議更新關於 mysqli.reconnect 選項建議的第一行描述。(實務注意事項 ;))
To Top