Verbinden Sie sich an einem bestimmten Port

PHP-Treiber herunterladen

Für eine Transmission Control Protocol (TCP)-Verbindung ohne expliziten Port ist der Standardport 1433. Verbindungen zu benannten Instanzen können den SQL Server Browser verwenden, um den Port der Instanz zu entdecken. Um TCP und einen bestimmten Port explizit auszuwählen, verwenden Sie tcp:<server>,<port>. Informationen zur Konfiguration der Serverseite finden Sie unter Konfigurieren eines Servers, sodass er auf einem bestimmten TCP-Port lauscht.

Vorbereiten des Endpunkts

  1. Fragen Sie den Serveradministrator nach dem Hostnamen und TCP-Port. Eine Clientverbindungszeichenfolge ändert nicht den Port, auf dem SQL Server lauscht.
  2. Lassen Sie diesen Port durch die Server-Firewall und die dazwischenliegenden Netzwerkkontrollen zu.
  3. Setzen Sie SQL_SERVER nur auf den Hostnamen, SQL_PORT auf die Dezimalportnummer und SQL_DATABASE auf den Datenbanknamen. Die Programme erstellen tcp:<server>,<port>. Benutze ein Komma vor dem Port, nicht einen Doppelpunkt.
  4. Legen Sie SQL_USER und SQL_PASSWORD für diese SQL-Authentifizierungsbeispiele über die Konfiguration geschützter Prozesse fest. Für integrierte oder Microsoft Entra-Authentifizierung verwenden Sie die entsprechenden Anmeldeeinstellungen aus Verbinden mit dem Server.

Ein expliziter Port vermeidet die Instanz-Port-Entdeckung über den SQL Server Browser. Halte den Server-Host-Namen konsistent mit seinem Zertifikat. Keines der beiden Beispiele deaktiviert die Zertifikatsvalidierung.

Speichere den tatsächlichen Datenbanknamen, Benutzernamen und Passwort in den Umgebungsvariablen. Beide Programme escapen diese Werte einmal für die ODBC-ähnliche Verbindungsverarbeitung des PHP-Treibers, indem schließende geschweifte Klammern verdoppelt und jeder Wert in geschweifte Klammern eingeschlossen werden. Für weitere Informationen siehe Verbinden mit dem Server.

SQLSRV

Speichere dieses Programm als connect-port-sqlsrv.php, und führe php connect-port-sqlsrv.php aus.

<?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

Speichere dieses separate Programm als connect-port-pdo.php, und führe php connect-port-pdo.php mit derselben Konfiguration aus.

<?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;
}

Für SQL_PORT=1433 gibt eines der Programme Folgendes aus:

Connected on TCP port 1433.

Die abgerufene int ist in SQLSRV vom PHP-Typ int und standardmäßig eine Zeichenkette in PDO_SQLSRV. Der Port ist Teil des Server-Arguments für SQLSRV und Teil des ServerDSN-Schlüsselworts für PDO_SQLSRV. In diesem Muster gibt es kein separates PDO-Stichwort Port .

Probleme bei der Portauswahl beheben

Symptom Action
Eine benannte Instanz funktioniert, aber ein expliziter Port nicht Bestätigen Sie den tatsächlichen Lauschport. Die Instanz könnte einen dynamischen Port verwenden, der sich nach einem Neustart geändert hat.
Bei TCP tritt ein Timeout auf Überprüfe den Listener und die Firewall vom PHP-Host. Ein offener Port beweist immer noch nicht, dass die SQL-Authentifizierung erfolgreich sein wird.
Die Validierung des Zertifikatsnamens schlägt nach Verwendung einer IP-Adresse fehl Verwenden Sie den Hostnamen auf dem Zertifikat mit dem expliziten Port. Deaktiviere die Validierung nicht wegen der Namensänderung.
Die Anwendung verbindet sich weiterhin woanders Überprüfe die Umgebung des laufenden PHP-Prozesses und die generierte Serverkonfiguration, ohne die Zugangsdaten auszudrucken. Starten Sie die Anwendung neu, falls ihre Konfiguration dies erfordert.

TCP-Auswahl und Instanzfindung gehören zu ODBC und der Netzwerkkonfiguration des Servers. PHP liefert den Endpunkt und meldet das Verbindungsergebnis. Für Azure SQL-Datenbank, Azure SQL Managed Instance, Azure Synapse Analytics, SQL Database in Fabric oder Warehouse in Fabric behalten Sie den dienstbereitgestellten Endpunkt und Port bei, anstatt einen beliebigen Port zu wählen. Die SQL-Login-Programme sind keine Authentifizierungsbeispiele für keines der beiden Fabric-Produkte. Weitere Informationen finden Sie unter Azure- und Fabric-Verbindungen.