Verbind op een gespecificeerde poort

PHP-stuurprogramma downloaden

Voor een Transmission Control Protocol (TCP)-verbinding zonder expliciete poort is de standaardpoort 1433. Verbindingen met naamgegeven instanties kunnen de SQL Server Browser gebruiken om de poort van de instantie te ontdekken. Om TCP en een specifieke poort expliciet te selecteren, gebruik tcp:<server>,<port>. Voor informatie over het configureren van de serverzijde, zie Een server configureren om te luisteren op een specifieke TCP-poort.

Bereid het endpoint voor

  1. Vraag de serverbeheerder naar de hostnaam en de TCP-poort. Een client-verbindingsreeks verandert niet de poort waarop SQL Server luistert.
  2. Sta die poort toe in de serverfirewall en tussenliggende netwerkcontroles.
  3. Stel SQL_SERVER alleen in op de hostnaam, SQL_PORT op het decimale poortnummer en SQL_DATABASE op de databasenaam. De programma's bouwen tcp:<server>,<port> op. Gebruik een komma voor de poort, geen dubbele punt.
  4. Stel SQL_USER en SQL_PASSWORD via protected process configuration in voor deze SQL-authenticatievoorbeelden. Voor geïntegreerde of Microsoft Entra-authenticatie gebruik je de juiste aanmeldingsinstellingen van Verbinden met de server.

Een expliciete poort maakt detectie van de instantiepoort via SQL Server Browser overbodig. Houd de hostnaam van de server consistent met zijn certificaat. Geen van beide voorbeelden schakelt certificaatvalidatie uit.

Sla de daadwerkelijke databasenaam, gebruikersnaam en wachtwoord op in de omgevingsvariabelen. Beide programma's escapen deze waarden eenmaal voor de ODBC-achtige verbindingsafhandeling van de PHP-driver door sluitende accolades te verdubbelen en elke waarde tussen accolades te plaatsen. Voor meer informatie, zie Verbinden met de server.

SQLSRV

Sla dit programma op als connect-port-sqlsrv.php, en voer php connect-port-sqlsrv.php uit.

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

Sla dit aparte programma op als connect-port-pdo.php, en voer php connect-port-pdo.php uit met dezelfde configuratie.

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

Voor SQL_PORT=1433, print elk van beide programma's:

Connected on TCP port 1433.

De gehaalde int is PHP int integer in SQLSRV en standaard een string in PDO_SQLSRV. De port maakt deel uit van het serverargument voor SQLSRV en maakt deel uit van het Server DSN-sleutelwoord voor PDO_SQLSRV. Er is geen apart PDO-trefwoord Port in dit patroon.

Problemen met de poortselectie oplossen

Symptom Action
Een benoemde instantie werkt, maar een expliciete poort niet. Bevestig de daadwerkelijke luisterende poort. De instantie kan een dynamische poort gebruiken die na een herstart is veranderd.
TCP verloopt Controleer de listener en firewall op de PHP-host. Een open poort bewijst nog steeds niet dat SQL-authenticatie zal slagen.
Certificaatnaamvalidatie faalt na gebruik van een IP-adres Gebruik de hostnaam op het certificaat met de expliciete poort. Schakel validatie niet uit om de naamswijziging te compenseren.
De applicatie maakt nog steeds elders verbinding Controleer de omgeving van het draaiende PHP-proces en de gegenereerde serverinstelling, zonder inloggegevens af te drukken. Herstart het applicatieproces als de configuratie dat vereist.

TCP-selectie en instantieontdekking behoren tot ODBC en de netwerkconfiguratie van de server. PHP levert het eindpunt en rapporteert het verbindingsresultaat. Voor Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics, SQL Database in Fabric of Warehouse in Fabric, behoud je het door de service geleverde endpoint en port in plaats van een willekeurige port te kiezen. De SQL-loginprogramma's zijn geen authenticatievoorbeelden voor een van beide Fabric-producten. Voor meer informatie, zie Azure en Fabric connecties.