明示的なポートのない伝送制御プロトコル(TCP)接続の場合、デフォルトのポートは1433です。 ネームドインスタンス接続はSQL Serverブラウザを使ってインスタンスのポートを検出できます。 TCPと特定のポートを明示的に選択するには、 tcp:<server>,<port>を使用します。 サーバー側の設定については、「特定のTCPポートで待ち受けるサーバーを設定する」をご覧ください。
エンドポイントを準備する
- サーバー管理者にホスト名とTCPポートを尋ねてください。 クライアントの接続文字列はSQL Serverが待ち受けるポートを変えません。
- そのポートがサーバーのファイアウォールと中間のネットワーク制御で許可されるようにしてください。
-
SQL_SERVERはホスト名のみ、SQL_PORTは10進数ポート番号、SQL_DATABASEはデータベース名に設定します。 プログラムはtcp:<server>,<port>を作成します。 ポートの前には、コロンではなくコンマを付けてください。 - これらのSQL認証例については、保護されたプロセス構成で
SQL_USERとSQL_PASSWORDを設定してください。 統合認証や Microsoft Entra 認証の場合は、「サーバーへの接続」の適切な資格情報の設定をご利用ください。
明示的なポートは、SQL Serverブラウザを通じたインスタンスポート検出を回避します。 サーバーホスト名は証明書と一致させてください。 どちらの例も証明書検証を無効にするものではありません。
実際のデータベース名、ユーザー名、パスワードを環境変数に保存します。 どちらのプログラムも、PHP ドライバーの ODBC 形式の接続処理に対応するため、閉じ中括弧を 2 つ重ね、各値を中括弧で囲むことで、これらの値をエスケープしています。 詳細は「 サーバーへの接続」をご覧ください。
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の Server DSNキーワードの一部です。 このパターンには個別の PDO Port キーワードはありません。
ポート選択のトラブルシューティング
| 症状: | アクション |
|---|---|
| 名前付きインスタンスは動作しますが、明示的なポートでは動作しません | 実際のリスニングポートを確認してください。 インスタンスは再起動後に変わった動的ポートを使うかもしれません。 |
| TCP がタイムアウトする | PHPホストのリスナーとファイアウォールを確認してください。 オープンポートでもSQL認証が成功する保証はありません。 |
| 証明書名の検証はIPアドレスを使用した後に失敗します | 証明書に記載されているホスト名と、明示的なポート番号を使用します。 名前変更を補うためにバリデーションを無効にしないでください。 |
| そのアプリケーションは別の場所に接続しています | 認証情報を印刷せずに実行中のPHPプロセス環境と生成されたサーバー設定を確認してください。 その設定で必要な場合はアプリケーションプロセスを再起動してください。 |
TCPの選択とインスタンス検出はODBCおよびサーバーのネットワーク構成に属します。 PHPはエンドポイントを提供し、接続結果を報告します。 Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics、Fabric の SQL データベース、または Fabric のウェアハウスでは、任意のポートを選ぶ代わりに、サービスによって提供されるエンドポイントとポートをそのまま使用してください。 SQLログインプログラムは、どちらのFabric製品でも認証の例ではありません。 詳細については、AzureおよびFabric接続を参照してください。