請注意,在所有 >= Windows 7 的伺服器上,主機名稱「localhost」會造成非常耗時的查詢(約 1 秒)。
這是因為自 Windows 7 起,hosts 檔案不再預先設定
127.0.0.1 localhost
了
因此,如果您發現連線建立時間很長,請嘗試改用「127.0.0.1」。
(PHP 5, PHP 7, PHP 8)
mysqli::__construct -- mysqli::connect -- mysqli_connect — 開啟與 MySQL 伺服器的新連線
物件導向風格
$hostname
= null
,$username
= null
,$password
= null
,$database
= null
,$port
= null
,$socket
= null
$hostname
= null
,$username
= null
,$password
= null
,$database
= null
,$port
= null
,$socket
= null
程序式風格
$hostname
= null
,$username
= null
,$password
= null
,$database
= null
,$port
= null
,$socket
= null
開啟與 MySQL 伺服器的連線。
hostname(主機名稱)
可以是主機名稱或 IP 位址。當傳入 null
時,將從 mysqli.default_host 取得值。如果可能,將使用管道而不是 TCP/IP 協定。如果同時提供主機名稱和埠號,例如 localhost:3308
,則會使用 TCP/IP 協定。
在主機名稱前加上 p:
可以開啟永久連線。連線池中開啟的連線會自動呼叫 mysqli_change_user()。
username(使用者名稱)
MySQL 使用者名稱,或 null
以根據 mysqli.default_user ini 選項假設使用者名稱。
password(密碼)
MySQL 密碼,或 null
以根據 mysqli.default_pw ini 選項假設密碼。
database(資料庫)
執行查詢時要使用的預設資料庫,或 null
。
port(埠號)
嘗試連線到 MySQL 伺服器的埠號,或 null
以根據 mysqli.default_port ini 選項假設埠號。
socket(通訊端)
應該使用的通訊端或命名管道,或 null
以根據 mysqli.default_socket ini 選項假設通訊端。
注意事項:
指定
socket
參數並不會明確決定連線到 MySQL 伺服器時要使用的連線類型。連線到 MySQL 資料庫的方式是由hostname
參數決定的。
mysqli_connect() 會傳回一個代表與 MySQL 伺服器連線的物件,如果失敗則傳回 false
。
mysqli::connect() 成功時傳回 true
,失敗時傳回 false
。在 PHP 8.1.0 之前,成功時傳回 null
。
如果啟用了 mysqli 錯誤報告 (MYSQLI_REPORT_ERROR
) 且請求的操作失敗,則會產生警告。此外,如果模式設定為 MYSQLI_REPORT_STRICT
,則會改為拋出 mysqli_sql_exception 例外。
範例 #1 mysqli::__construct() 範例
物件導向風格
<?php
/* 在嘗試建立連線之前,您應該啟用 mysqli 的錯誤報告 */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
/* 建立連線後設定所需的字元集 */
$mysqli->set_charset('utf8mb4');
printf("成功... %s\n", $mysqli->host_info);
程序式風格
<?php
/* 在嘗試建立連線之前,您應該啟用 mysqli 的錯誤報告 */
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
/* 建立連線後設定所需的字元集 */
mysqli_set_charset($mysqli, 'utf8mb4');
printf("成功... %s\n", mysqli_get_host_info($mysqli));
以上範例將輸出類似以下的內容:
Success... localhost via TCP/IP
範例 #2 擴展 mysqli 類別
<?php
class FooMysqli extends mysqli {
public function __construct($host, $user, $pass, $db, $port, $socket, $charset) {
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
parent::__construct($host, $user, $pass, $db, $port, $socket);
$this->set_charset($charset);
}
}
$db = new FooMysqli('localhost', 'my_user', 'my_password', 'my_db', 3306, null, 'utf8mb4');
範例 #3 手動錯誤處理
如果錯誤回報被停用,開發者有責任檢查和處理錯誤。
物件導向風格
<?php
error_reporting(0);
mysqli_report(MYSQLI_REPORT_OFF);
$mysqli = new mysqli('localhost', 'my_user', 'my_password', 'my_db');
if ($mysqli->connect_errno) {
throw new RuntimeException('mysqli 連線錯誤:' . $mysqli->connect_error);
}
/* 建立連線後設定所需的字元集 */
$mysqli->set_charset('utf8mb4');
if ($mysqli->errno) {
throw new RuntimeException('mysqli 錯誤:' . $mysqli->error);
}
程序式風格
<?php
error_reporting(0);
mysqli_report(MYSQLI_REPORT_OFF);
$mysqli = mysqli_connect('localhost', 'my_user', 'my_password', 'my_db');
if (mysqli_connect_errno()) {
throw new RuntimeException('mysqli 連線錯誤:' . mysqli_connect_error());
}
/* 建立連線後設定所需的字元集 */
mysqli_set_charset($mysqli, 'utf8mb4');
if (mysqli_errno($mysqli)) {
throw new RuntimeException('mysqli 錯誤:' . mysqli_error($mysqli));
}
注意事項:
MySQLnd 永遠假設伺服器預設的字元集。這個字元集會在連線交握/驗證期間傳送,MySQLnd 將會使用它。
Libmysqlclient 使用在 my.cnf 中設定的預設字元集,或者在呼叫 mysqli_real_connect() 之前,但在 mysqli_init() 之後,透過明確呼叫 mysqli_options() 來設定。
注意事項:
僅限物件導向風格:如果連線失敗,仍然會回傳一個物件。要檢查連線是否失敗,請使用 mysqli_connect_error() 函式或 mysqli->connect_error 屬性,如前面的範例所示。
注意事項:
如果需要設定選項,例如連線逾時,則必須使用 mysqli_real_connect()。
注意事項:
不帶參數呼叫建構函式與呼叫 mysqli_init() 相同。
注意事項:
錯誤訊息「無法建立 TCP/IP 通訊端 (10106)」通常表示 variables_order 設定指令不包含字元
E
。在 Windows 系統上,如果未複製環境變數,SYSTEMROOT
環境變數將無法使用,PHP 將無法載入 Winsock。
請注意,在所有 >= Windows 7 的伺服器上,主機名稱「localhost」會造成非常耗時的查詢(約 1 秒)。
這是因為自 Windows 7 起,hosts 檔案不再預先設定
127.0.0.1 localhost
了
因此,如果您發現連線建立時間很長,請嘗試改用「127.0.0.1」。
如果要避免奇怪的字串問題,請在建立連線後使用 set_charset("utf8")。我不明白為什麼文件沒有警告這類事情。
我們花了很長時間才弄清楚發生了什麼事,因為我們使用了 mb_detect_encoding,它顯示一切都是 UTF-8,但顯示結果卻是錯誤的。如果我們使用 iconv 從 ISO-8859-1 轉換為 UTF-8,字串看起來就沒問題,即使資料庫中的所有內容都具有正確的校對。所以最後,是連線本身的問題,雖然這個函式的註釋提到了預設字元集,但在處理 UTF 和 PHP/MySQL 時,它讀起來幾乎像是一個旁註,而不是一個核心問題。
與 mysql_connect 不同,這裡有一個獨立的連接埠參數。然而,在主機參數上使用 host:port 確實有效。
有一個需要注意的地方。如果主機是 'localhost',則連接埠會被忽略,無論您使用的是連接埠參數還是我上面提到的隱式語法。這是因為 'localhost' 會讓它使用 Unix 通訊端而不是 TCP/IP。
給所有想使用 MySQLi 持續連線功能的人一點提醒:很重要的一點是,PHP 會針對每個處理程序中的每個資料庫使用者開啟並保持一個連線。
這表示,如果您正在託管多個應用程式,每個應用程式都有自己的資料庫使用者(這是良好的做法),那麼您最終會增加 PHP 可能保持開啟的連線數量。
例如,如果您將 PHP 配置為最多八個工作程序,並且您經常使用四個不同的資料庫使用者,那麼您的 MySQL 伺服器將需要接受至少 32 個連線,否則它將耗盡連線。
然而,如果您想要減少連線數量,您可以改用一個「訪客」使用者(除了登入之外沒有其他權限)開啟連線,然後使用 ->change_user() 切換到一個具有更多權限的使用者,並在完成後切換回訪客使用者。由於所有連線都屬於訪客使用者,PHP 應該只會為每個工作程序保持一個連線。
如果您想透過替代埠(非 3306)連線,例如當您使用 ssh 通道連線到另一台主機時,使用「localhost」作為主機名稱將無法運作。
使用 127.0.0.1 則可以運作。顯然,如果您將主機指定為「localhost」,建構函式會忽略作為引數指定給建構函式的埠。