MySQL 伺服器支援使用不同的傳輸層進行連線。連線使用 TCP/IP、Unix 網域通訊端或 Windows 具名管道。
主機名稱 localhost
有特殊含義。它與 Unix 網域通訊端的使用綁定。要開啟到 localhost 的 TCP/IP 連線,必須使用 127.0.0.1
而不是主機名稱 localhost
。
範例 #1 localhost 的特殊含義
<?php
$mysqli = new mysqli("localhost", "user", "password", "database");
echo $mysqli->host_info . "\n";
$mysqli = new mysqli("127.0.0.1", "user", "password", "database", 3306);
echo $mysqli->host_info . "\n";
上面的範例會輸出
Localhost via UNIX socket 127.0.0.1 via TCP/IP
連線參數預設值
根據使用的連線函數,可以省略各種參數。如果未提供參數,則擴充功能會嘗試使用 PHP 設定檔中設定的預設值。
範例 #2 設定預設值
mysqli.default_host=192.168.2.27 mysqli.default_user=root mysqli.default_pw="" mysqli.default_port=3306 mysqli.default_socket=/tmp/mysql.sock
然後將產生的參數值傳遞給擴充功能使用的客戶端程式庫。如果客戶端程式庫偵測到空白或未設定的參數,則它可能會預設為程式庫內建的值。
內建連線程式庫預設值
如果 host 值未設定或為空白,則客戶端程式庫會預設為 localhost
上的 Unix 通訊端連線。如果 socket 未設定或為空白,且要求 Unix 通訊端連線,則會嘗試連線到 /tmp/mysql.sock
上的預設通訊端。
在 Windows 系統上,客戶端程式庫會將主機名稱 .
解釋為嘗試開啟基於 Windows 具名管道的連線。在這種情況下,socket 參數會被解釋為管道名稱。如果未給定或為空白,則通訊端(管道名稱)會預設為 \\.\pipe\MySQL
。
如果沒有要建立基於 Unix 網域通訊端或 Windows 具名管道的連線,且 port 參數值未設定,則程式庫會預設為埠 3306
。
mysqlnd 程式庫和 MySQL 客戶端程式庫 (libmysqlclient) 實作相同的邏輯來判斷預設值。
連線選項
連線選項可用於,例如,設定在連線時執行的初始化命令,或要求使用特定的字元集。連線選項必須在建立網路連線之前設定。
要設定連線選項,連線操作必須分三個步驟執行:使用 mysqli_init() 或 mysqli::__construct() 建立連線控制代碼、使用 mysqli::options() 設定要求的選項,以及使用 mysqli::real_connect() 建立網路連線。
連線集區
mysqli 擴充功能支援持久資料庫連線,這是一種特殊的集區連線。預設情況下,腳本開啟的每個資料庫連線都會在執行期間由使用者明確關閉,或在腳本結束時自動釋放。持久連線則不是。相反,如果使用相同的使用者名稱、密碼、通訊端、埠和預設資料庫開啟到相同伺服器的連線,則會將其放入集區以供稍後重複使用。重複使用可以節省連線的額外負擔。
每個 PHP 程序都使用自己的 mysqli 連線集區。根據網頁伺服器部署模型,一個 PHP 程序可能會服務一個或多個請求。因此,集區連線可能會被一個或多個腳本後續使用。
持久連線
如果無法在連線集區中找到給定主機、使用者名稱、密碼、通訊端、埠和預設資料庫組合的未使用持久連線,則 mysqli 會開啟新的連線。可以使用 PHP 指令 mysqli.allow_persistent 啟用和停用持久連線。腳本開啟的連線總數可以使用 mysqli.max_links 限制。每個 PHP 程序的持久連線最大數量可以使用 mysqli.max_persistent 限制。請注意,網頁伺服器可能會產生許多 PHP 程序。
關於持久連線的一個常見抱怨是,它們的狀態在重複使用之前不會重設。例如,開啟和未完成的事務不會自動回滾。此外,在將連線放入集區和重複使用之間的這段時間內發生的授權變更也不會反映出來。這可能被視為不良的副作用。相反,名稱 persistent
可能會被理解為承諾狀態會被持久化。
mysqli 擴充功能支援對持久連線的兩種解釋:狀態持久化,以及在重複使用之前重設狀態。預設值是重設。在重複使用持久連線之前,mysqli 擴充功能會隱式呼叫 mysqli::change_user() 以重設狀態。持久連線對使用者來說就像剛開啟一樣。看不到先前使用的任何痕跡。
mysqli::change_user() 呼叫是一項昂貴的操作。為了獲得最佳效能,使用者可能需要使用設定的編譯旗標 MYSQLI_NO_CHANGE_USER_ON_PCONNECT
重新編譯擴充功能。
是否選擇安全行為或最佳效能,取決於使用者。兩者都是有效的最佳化目標。為了方便使用,在犧牲最大效能的情況下,安全行為已成為預設值。
參見