Collegati a una porta specifica

Download del driver PHP

Per una connessione Transmission Control Protocol (TCP) senza una porta esplicita, la porta predefinita è 1433. Le connessioni named-instance possono utilizzare SQL Server Browser per scoprire la porta dell'istanza. Per selezionare esplicitamente TCP e una porta specifica, usa tcp:<server>,<port>. Per informazioni sulla configurazione del lato server, vedi Configura un server per ascoltare su una specifica porta TCP.

Prepara l'endpoint

  1. Chiedi all'amministratore del server il nome host e la porta TCP. Una stringa di connessione client non cambia la porta su cui SQL Server ascolta.
  2. Consenti a quella porta di passare attraverso il firewall del server e i controlli di rete intermedi.
  3. Imposta SQL_SERVER solo sul nome host, SQL_PORT sul numero della porta decimale e SQL_DATABASE sul nome del database. I programmi creano tcp:<server>,<port>. Usa una virgola prima del numero di porta, non i due punti.
  4. Imposta SQL_USER e SQL_PASSWORD tramite la configurazione protetta del processo per questi esempi di autenticazione SQL. Per l'autenticazione integrata o Microsoft Entra, utilizza le impostazioni di credenziali appropriate da Connessione al server.

Una porta esplicita evita la scoperta della porta di istanza tramite SQL Server Browser. Mantieni il nome host del server coerente con il suo certificato. Nessuno dei due esempi disabilita la validazione dei certificati.

Memorizza il nome effettivo del database, il nome utente e la password nelle variabili ambientali. Entrambi i programmi eseguono l'escape di questi valori una volta per la gestione delle connessioni in stile ODBC del driver PHP, raddoppiando le parentesi graffe di chiusura e racchiudendo ogni valore tra parentesi graffe. Per maggiori informazioni, vedi Connessione al server.

SQLSRV

Salva questo programma come connect-port-sqlsrv.php, ed esegui 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

Salva questo programma separato come connect-port-pdo.php, e esegui php connect-port-pdo.php con la stessa configurazione.

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

Per SQL_PORT=1433, entrambi i programmi stampano:

Connected on TCP port 1433.

L'int recuperato è un int PHP in SQLSRV e una stringa per impostazione predefinita in PDO_SQLSRV. La porta fa parte dell'argomento server per SQLSRV e parte della Server parola chiave DSN per PDO_SQLSRV. Non esiste una parola chiave PDO Port separata in questo schema.

Risolvere i problemi di selezione della porta

Sintomo Action
Un'istanza denominata funziona, ma una porta esplicita no Conferma la porta di ascolto effettiva. L'istanza potrebbe usare una porta dinamica che è cambiata dopo un riavvio.
Timeout del TCP Controlla il listener e il firewall dall'host PHP. Una porta aperta non dimostra comunque che l'autenticazione SQL avrà successo.
La validazione del nome del certificato fallisce dopo aver utilizzato un indirizzo IP Usa il nome host presente nel certificato con la porta esplicita. Non disabilitare la validazione per compensare il cambio di nome.
L'applicazione si collega ancora altrove Controlla l'ambiente del processo PHP in esecuzione e l'impostazione del server generato, senza stampare le credenziali. Riavvia il processo dell'applicazione se la configurazione lo richiede.

La selezione TCP e la scoperta dell'istanza appartengono a ODBC e alla configurazione di rete del server. PHP fornisce l'endpoint e riporta il risultato della connessione. Per database SQL di Azure, Istanza gestita di SQL di Azure, Azure Synapse Analytics, database SQL in Fabric o Warehouse in Fabric, mantenere l'endpoint e la porta forniti dal servizio invece di scegliere una porta arbitraria. I programmi di login SQL non sono esempi di autenticazione per nessuno dei due prodotti Fabric. Per maggiori informazioni, vedi Azure e Fabric connessioni.