對於未明確指定連接埠的傳輸控制協定(TCP)連線,預設連接埠為 1433。 命名實例連線可使用 SQL Server 瀏覽器來發現實例的埠。 若要明確選擇 TCP 及特定埠口,請使用 tcp:<server>,<port>。 關於如何設定伺服器端的資訊,請參見 「設定伺服器監聽特定 TCP 埠」。
準備端點
- 請向伺服器管理員詢問主機名稱和 TCP 埠口。 客戶端的 連接字串 不會改變 SQL Server 監聽的埠口。
- 允許該埠通過伺服器防火牆及其間的網路控管設備。
- 只設定
SQL_SERVER主機名稱、SQL_PORT十進位連接埠號碼,以及SQL_DATABASE資料庫名稱。 這些程式會建構tcp:<server>,<port>。 在連接埠前加逗號,不要加冒號。 - 透過受保護的處理程序設定,為這些 SQL 驗證範例設定
SQL_USER和SQL_PASSWORD。 若要使用整合或 Microsoft Entra 驗證,請使用 連線到伺服器 中的適當認證設定。
明確的埠碼可避免透過 SQL Server 瀏覽器進行實例埠偵測。 保持伺服器主機名稱與其憑證一致。 這兩個例子都不會禁用憑證驗證。
將實際的資料庫名稱、使用者名稱和密碼存入環境變數中。 兩個程式都會跳脫這些值一次,以實現 PHP 驅動程式類似 ODBC 的連線處理,方法是將右大括號重複一次,並將每個值用大括號括起來。 更多資訊請參見 「連接伺服器」。
SQLSRV
將此程式儲存為 connect-port-sqlsrv.php,並執行 php connect-port-sqlsrv.php。
<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_PORT', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Set $name before running this example.");
}
$config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$port = filter_var($config['SQL_PORT'], FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 65535],
]);
if ($port === false) {
throw new RuntimeException('SQL_PORT must be an integer from 1 through 65535.');
}
$serverName = 'tcp:' . $config['SQL_SERVER'] . ',' . $port;
$conn = sqlsrv_connect($serverName, [
'Database' => $config['SQL_DATABASE'],
'UID' => $config['SQL_USER'],
'PWD' => $config['SQL_PASSWORD'],
'Encrypt' => true,
'TrustServerCertificate' => false,
'LoginTimeout' => 30,
]);
if ($conn === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$stmt = null;
try {
$stmt = sqlsrv_query($conn, 'SELECT CAST(1 AS int) AS Connected');
if ($stmt === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
if ($row === false) {
throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
if ($row !== ['Connected' => 1]) {
throw new RuntimeException('Unexpected connection-test result.');
}
echo "Connected on TCP port $port.", PHP_EOL;
} finally {
if (is_resource($stmt)) {
sqlsrv_free_stmt($stmt);
}
sqlsrv_close($conn);
}
PDO_SQLSRV
將這個獨立程式儲存為 connect-port-pdo.php,並以相同的設定執行 php connect-port-pdo.php 。
<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_PORT', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$value = getenv($name);
if ($value === false || $value === '') {
throw new RuntimeException("Set $name before running this example.");
}
$config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
$config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$port = filter_var($config['SQL_PORT'], FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 65535],
]);
if ($port === false) {
throw new RuntimeException('SQL_PORT must be an integer from 1 through 65535.');
}
$serverName = 'tcp:' . $config['SQL_SERVER'] . ',' . $port;
$database = $config['SQL_DATABASE'];
$pdo = new PDO(
"sqlsrv:Server=$serverName;Database=$database;Encrypt=true;"
. "TrustServerCertificate=false;LoginTimeout=30",
$config['SQL_USER'],
$config['SQL_PASSWORD'],
[PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
);
$stmt = null;
try {
$stmt = $pdo->query('SELECT CAST(1 AS int) AS Connected');
if ($stmt->fetch(PDO::FETCH_ASSOC) !== ['Connected' => '1']) {
throw new RuntimeException('Unexpected connection-test result.');
}
echo "Connected on TCP port $port.", PHP_EOL;
} finally {
$stmt = null;
$pdo = null;
}
對 SQL_PORT=1433 而言,其中一個程式會列印:
Connected on TCP port 1433.
擷取的 int 在 SQLSRV 中是 PHP int,在 PDO_SQLSRV 中預設是字串。 埠號是 SQLSRV 伺服器參數的一部分,也是 PDO_SQLSRV 的 DSN Server 關鍵字的一部分。 此模式中沒有獨立的 PDO Port 關鍵字。
疑難排解埠選擇
| 徵兆 | Action |
|---|---|
| 命名實例是可行的,但明確指定的連接埠不行 | 確認實際的監聽連接埠。 該實例可能使用重新啟動後變動的動態埠。 |
| TCP 超時 | 檢查 PHP 主機的監聽器和防火牆。 開放埠仍無法證明 SQL 認證會成功。 |
| 使用 IP 位址後,憑證名稱驗證會失敗 | 使用憑證上的主機名稱和明確指定的連接埠。 不要為了名稱變更而關閉驗證功能。 |
| 應用程式仍能連接到其他位置 | 檢查執行中的 PHP 程序環境和產生的伺服器設定,但不要列印憑證。 如果設定需要,請重新啟動應用程式。 |
TCP 的選擇與實例發現屬於 ODBC 及伺服器的網路設定。 PHP 提供端點並回報連線結果。 對於 Azure SQL Database、Azure SQL 受控執行個體、Azure Synapse Analytics、Fabric 中的 SQL 資料庫,或 Fabric 中的 Warehouse,請保留服務提供的端點和埠,而非選擇任意埠。 SQL 登入程式並非任一 Fabric 產品的認證範例。 欲了解更多資訊,請參閱 Azure 與 Fabric 連線。