Connessione al server

Download del driver PHP

Usa questa guida per aprire una connessione, verificare i valori ricevuti da PHP e rilasciare la connessione quando il lavoro termina. I programmi utilizzano l'autenticazione SQL Server per un database di test SQL Server locale o remoto. Per connessioni Azure e Fabric senza password, usa Connect to Azure SQL e Fabric SQL.

SQLSRV accetta un nome server e un array associativo di opzioni di connessione. PDO_SQLSRV implementa PHP Data Objects (PDO) e accetta una stringa di nome sorgente dati (DSN), argomenti di credenziali separati e un array di attributi PDO. Entrambi utilizzano il driver Microsoft ODBC per SQL Server. Una connessione che lavora con un'API non rende intercambiabili i nomi delle opzioni o i tipi PHP dell'altra API.

Prima che tu ti connetta

  1. Installa un runtime PHP supportato e un driver Microsoft ODBC, e carica l'estensione PHP che intendi usare.
  2. Controlla il processo PHP che gestisce la tua applicazione. Esegui php --ini per trovare la configurazione in riga di comando e php -m per elencare le sue estensioni caricate. SQLSRV richiede sqlsrv. PDO_SQLSRV richiede PDO e pdo_sqlsrv. Un server Web può usare un runtime e un account diversi da quelli del tuo terminale php.ini.
  3. Ottieni l'indirizzo del server, il nome del database e un'identità con il permesso di connettersi. Un login di database non concede automaticamente il permesso a ogni tabella.
  4. Configura l'accesso alla rete e un certificato server affidabile. Questi programmi richiedono esplicitamente la crittografia e la validazione dei certificati. Connettiti con il nome host sul certificato invece di sostituire un indirizzo IP che il certificato non copre.

Imposta queste variabili nell'ambiente del processo PHP, usando la tua shell, lo strumento di sviluppo o la configurazione di hosting. Non fare commit di un file di password né stampare le variabili d'ambiente.

Variable Value
SQL_SERVER Il nome host del server, opzionalmente prefissato da tcp: e seguito da ,<port>.
SQL_DATABASE Un database esistente accessibile con il tuo login.
SQL_USER Un login SQL Server.
SQL_PASSWORD La password di quell'accesso, fornita tramite una configurazione protetta.

Leggi le impostazioni di server e database dalla configurazione dell'applicazione attendibile, non dai parametri delle richieste web. L'esempio del PDO colloca queste impostazioni in un DSN. Mantieni le parole chiave di connessione sotto il controllo dell'applicazione.

Memorizza il nome effettivo del database, il nome utente e la password nelle variabili ambientali, senza aggiungere o raddoppiare le parentesi graffe tu stesso. Entrambe le estensioni PHP richiedono escape in stile ODBC anche per le opzioni dell'array SQLSRV e gli argomenti del costruttore PDO: raddoppiare ogni parentesi graffa chiusa e racchiudere il valore tra parentesi graffe. Ogni programma fa questo una volta prima di passare questi valori al driver. Le parentesi esterne conservano le parentesi letterali all'inizio e alla fine di un valore e impediscono che i punti e virgola all'interno del nome del database separino le impostazioni DSN del PDO. Questo escape è separato dal binding dei parametri di Transact-SQL (T-SQL).

Apri, interroga e chiudi con SQLSRV

Salva questo programma come connect-sqlsrv.php, ed esegui php connect-sqlsrv.php. Esegue una query T-SQL senza creare tabelle o modificare dati. CharacterSet seleziona UTF-8 per i dati dei caratteri; non cambia i tipi di colonne o la collazione del database.

<?php
$config = [];
foreach (['SQL_SERVER', '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]) . '}';
}

$conn = sqlsrv_connect($config['SQL_SERVER'], [
    'Database' => $config['SQL_DATABASE'],
    'UID' => $config['SQL_USER'],
    'PWD' => $config['SQL_PASSWORD'],
    'Encrypt' => true,
    'TrustServerCertificate' => false,
    'LoginTimeout' => 30,
    'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
    throw new RuntimeException(print_r(sqlsrv_errors(), true));
}

$stmt = null;
try {
    $sql = "SELECT CAST(42 AS int) AS Value, N'caf' + NCHAR(233) AS Label, "
        . "CAST(NULL AS int) AS Missing";
    $stmt = sqlsrv_query($conn, $sql, [], ['QueryTimeout' => 30]);
    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 !== ['Value' => 42, 'Label' => "caf\u{00e9}", 'Missing' => null]) {
        throw new RuntimeException('Unexpected SQLSRV values or PHP types.');
    }
    echo json_encode($row, JSON_THROW_ON_ERROR), PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

Output previsto:

{"Value":42,"Label":"caf\u00e9","Missing":null}

La connessione e l'istruzione sono risorse PHP, handle che passi alle sqlsrv_* funzioni. Controlla false prima di usare una delle due maniglie. Recupera sqlsrv_errors() immediatamente dopo un errore perché una chiamata SQLSRV successiva può sostituire la raccolta errori.

SQLSRV_FETCH_ASSOC restituisce un array associativo con nomi di colonne come chiavi. SQLSRV_FETCH_NUMERIC restituisce chiavi numeriche a base zero; il predefinito SQLSRV_FETCH_BOTH include entrambe le forme. Per sqlsrv_fetch_array(), null significa niente più righe e false significa un errore. Un SQL NULL all'interno di una riga è PHP null; non significa che la riga sia mancante. Da usare === quando si distinguono questi valori.

Apri, interroga e chiudi con PDO_SQLSRV

Salva questo programma separato come connect-pdo.php, ed esegui php connect-pdo.php con lo stesso ambiente. sqlsrv: seleziona PDO_SQLSRV, non il driver PDO generico di PHP, PDO_ODBC.

<?php
$config = [];
foreach (['SQL_SERVER', '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]) . '}';
}
$server = $config['SQL_SERVER'];
$database = $config['SQL_DATABASE'];
$pdo = new PDO(
    "sqlsrv:Server=$server;Database=$database;Encrypt=true;"
    . "TrustServerCertificate=false;LoginTimeout=30",
    $config['SQL_USER'],
    $config['SQL_PASSWORD'],
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
    ]
);

$stmt = null;
try {
    $sql = "SELECT CAST(42 AS int) AS Value, N'caf' + NCHAR(233) AS Label, "
        . "CAST(NULL AS int) AS Missing";
    $stmt = $pdo->prepare($sql, [PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 30]);
    $stmt->execute();
    $row = $stmt->fetch();
    if ($row !== ['Value' => '42', 'Label' => "caf\u{00e9}", 'Missing' => null]) {
        throw new RuntimeException('Unexpected PDO_SQLSRV values or PHP types.');
    }
    echo json_encode($row, JSON_THROW_ON_ERROR), PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

Output previsto:

{"Value":"42","Label":"caf\u00e9","Missing":null}

PDO_SQLSRV restituisce questa colonna int come stringa PHP di default. Per richiedere i tipi numerici PHP per colonne numeriche supportate, imposta PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE a true. Non usare un PHP cast indiscriminatamente per valori decimali ; una conversione in virgola mobile può perdere precisione.

Gli attributi PDO sono impostazioni sull'oggetto connessione o sull'oggetto statement. PDO::ATTR_ERRMODE con PDO::ERRMODE_EXCEPTION fa sì che i fallimenti delle operazioni del database lancino PDOException. La costruzione della connessione genera un'eccezione in caso di errore indipendentemente da quell'impostazione. PDO::FETCH_ASSOC dà chiavi nominate, PDO::FETCH_NUM dà chiavi numeriche con indice a partire da zero e PDO::FETCH_BOTH fornisce entrambe. fetch() restituisce false alla fine del risultato; i valori SQL NULL all'interno di una riga rimangono PHP null.

Questi programmi da riga di comando permettono agli errori di fermare l'esecuzione. In un'applicazione web, individua eccezioni nel codice che gestisce la richiesta. Registra i dettagli diagnostici in log protetti e restituisci una risposta generica all'errore. Non inviare sqlsrv_errors()tracce di eccezione, stringhe di connessione o token a un browser.

Scegliere una modalità di autenticazione

Mode Usare per Vedi
Autenticazione di SQL Server SQL Server on-premise, container e Azure SQL quando Microsoft Entra ID non è disponibile Connettiti usando l'autenticazione SQL Server
Autenticazione integrata (nessun nome utente o password nelle impostazioni di connessione) Identità Windows, o client Linux/macOS configurati per Kerberos Connettersi tramite l'autenticazione di Windows
Microsoft Entra ID (Authenticationo AccessToken parola chiave) Azure SQL e Fabric SQL target configurati per Microsoft Entra ID Connettersi con l'autenticazione di Microsoft Entra

Per l'autenticazione SQL, SQLSRV prende UID e PWD nel suo array di opzioni di connessione. PDO_SQLSRV prende il nome utente e la password come secondo e terzo argomento per new PDO(), non come parole chiave DSN. Per un access token, SQLSRV prende AccessToken in carico l'array delle opzioni, mentre PDO_SQLSRV lo prende nel DSN.

Se ometti nome utente, password, Authentication, e AccessToken, entrambi i driver richiedono l'autenticazione integrata da ODBC usando Trusted_Connection=Yes. Su Linux e macOS, questa richiesta richiede un ticket Kerberos valido e una configurazione di autenticazione integrata ODBC. Non dà a un account locale arbitrario l'accesso a un server remoto.

Configura la connessione e i suoi statement

Le impostazioni di connessione si applicano alla sessione che apri. Le impostazioni delle istruzioni si applicano a una particolare query. Imposta timeout e tipi di risultato esplicitamente quando la tua applicazione ha bisogno di valori diversi dai valori predefiniti.

Purpose SQLSRV PDO_SQLSRV Proprietario comportamento
Endpoint e database Argomento del server e opzione Database. Server e Database parole chiave DSN. ODBC e il target SQL.
Credenziali SQL opzioni UID e PWD. Argomenti per nome utente e password del costruttore. Gestione delle credenziali di estensione e autenticazione dei server.
Autenticazione Microsoft Entra Authentication opzione, oppure l'opzione separata AccessToken . Authentication o AccessToken parola chiave DSN, con le credenziali omesse per un token esterno. autenticazione ODBC; l'applicazione acquisisce token esterni.
Encryption Encrypt => true. Encrypt=true nella DSN. Sicurezza dei trasporti ODBC.
Convalida del certificato TrustServerCertificate => false. TrustServerCertificate=false nella DSN. ODBC e la configurazione del trust dei certificati del sistema operativo.
Timeout per l'istituzione della connessione LoginTimeout Opzione di connessione, in pochi secondi. LoginTimeout Parola chiave DSN, in secondi. ODBC. Non è il timeout di esecuzione dell'istruzione.
Timeout query QueryTimeout Opzione dichiarazione, in secondi. PDO::SQLSRV_ATTR_QUERY_TIMEOUT, sulla connessione o istruzione. Gestione delle istruzioni Extension e ODBC.
Codifica dei caratteri CharacterSet => 'UTF-8' Opzione di connessione. PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8. Conversione delle estensioni PHP. PDO_SQLSRV è predefinito su UTF-8; SQLSRV è predefinito sulla codifica di sistema.
Oggetti data e ora ReturnDatesAsStrings è false di default, quindi le colonne data e ora restituiscono DateTime oggetti. stringhe di default; usate PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE per richiedere oggetti. Conversione del tipo di estensioni PHP.
Set di risultati attivi multipli (MARS) MultipleActiveResultSets Opzione di connessione. MultipleActiveResultSets Parola chiave DSN. ODBC e supporto della destinazione. Entrambe le estensioni lo abilitano di default; disabilitalo per Warehouse in Fabric.
Recupero da inattività ConnectRetryCount e ConnectRetryInterval opzioni di connessione. Le stesse parole chiave DSN. ODBC. Non riprovano operazioni di applicazione arbitrarie.

Per l'elenco completo delle parole chiave, i valori consentiti e i valori predefiniti, vedi Opzioni di Connessione. Non mettere i nomi costanti CharacterSet, QueryTimeout o PDO:: in un DSN PDO.

Gestire la durata della connessione

Apri una connessione quando una richiesta o un lavoro necessita di lavoro nel database. Riutilizzalo durante quella richiesta o lavoro, poi rilascialo quando hai finito. Non connettere e disconnettere per ogni riga. In un lavoratore di lunga durata, rilascia gli estratti conto e completa ogni transazione prima di accettare il lavoro successivo.

SQLSRV chiude gli statement SQL associati quando chiudi la sua connessione. Liberare esplicitamente gli statement in anticipo libera risorse senza interrompere la connessione. Per il PDO, assegnare $pdo = null rimuove solo il riferimento di quella variabile. A PDOStatement o un'altra variabile può comunque mantenere la connessione. Rilascia anche quelle reference. closeCursor() rilascia i risultati in sospeso affinché l'istruzione possa essere riutilizzata; non è un metodo di chiusura della connessione.

Entrambe le API iniziano in modalità autocommit: un'istruzione eseguita correttamente viene confermata automaticamente senza un commit separato dell'applicazione, a meno che tu non inizi una transazione. Per un gruppo di scritture che devono avere successo o fallire insieme, usare sqlsrv_begin_transaction() o $pdo->beginTransaction(), poi fare commit o annullare esplicitamente. Chiudere una connessione con una transazione in sospeso tenta un rollback, non un commit. Non affidarti alla pulizia all'arresto per implementare la tua politica di transazione. Per esempi completi, consulta Eseguire transazioni.

Rilasciare un handle di connessione PHP non chiude necessariamente la sua connessione fisica di rete. Il pooling ODBC può conservarlo per il riutilizzo. Il pooling non è un motivo per conservare risorse PHP a tempo indeterminato, e PDO_SQLSRV non supporta PDO::ATTR_PERSISTENT => true. Per la configurazione di pooling specifica per piattaforma, vedi Connection pooling.

Applica la guida al tuo target SQL

I pattern handle, fetch e cleanup si applicano a entrambe le estensioni sui target SQL supportati. I punti di connessione, l'autenticazione, l'accesso alla rete e le capacità SQL variano.

Target Adattamento
SQL Server I programmi utilizzano un login SQL. L'autenticazione integrata è un'altra scelta quando configuri l'identità del processo PHP.
Database SQL di Microsoft Azure Usa il nome dell'host del server logico e il database esplicito. Preferisci l'autenticazione Microsoft Entra invece delle credenziali SQL in questi programmi.
Istanza gestita di SQL di Azure (Istanza gestita di Azure SQL) Usa l'endpoint dell'istanza e i suoi requisiti di accesso alla rete. Non dare per scontato che un endpoint privato sia raggiungibile dalla tua postazione di lavoro.
Azure Synapse Analytics Usa l'endpoint del pool SQL e controlla il suo supporto T-SQL prima di adattare query che creano o modificano oggetti.
Database SQL di Microsoft Fabric Utilizza i dettagli della connessione al relativo database e l'autenticazione Microsoft Entra. Non sostituire l'endpoint di analisi SQL.
Magazzino in Microsoft Fabric Usa il suo endpoint e database del warehouse, l'autenticazione Microsoft Entra e MultipleActiveResultSets=false.

Per la configurazione specifica del servizio, vedi Azure e connessioni Fabric.

Risolvere i problemi di connessione

Inizia con il passaggio che ha fallito. Un controllo riuscito del Transmission Control Protocol (TCP) non dimostra che l'autenticazione o la validazione del certificato siano riuscite.

Sintomo Seleziona
Call to undefined function sqlsrv_connect() Il processo PHP in esecuzione non ha caricato sqlsrv. Controlla i suoi php.ini e gli avvisi di avvio.
Report PDO could not find driver Conferma che pdo_sqlsrv sia caricato in quel processo e sqlsrv appaia in PDO::getAvailableDrivers().
Il driver ODBC non è stato trovato Installa il driver Microsoft ODBC e controlla la sua registrazione e architettura. L'installazione di un'estensione PHP non installa ODBC.
Timeout connessione o server non trovato Controlla il nome del server, la porta, la risoluzione del nome, il routing, le regole del firewall e se SQL Server ascolta su TCP.
La validazione della catena di certificati o dell'hostname non riesce Installa la catena di fiducia corretta e usa il nome host del certificato. Non trattate TrustServerCertificate=true come una correzione per la produzione.
L'accesso fallisce o il database non può essere aperto Controlla la modalità di autenticazione, il nome del database, la mappatura login/utente e i permessi. Omettere le credenziali richiede autenticazione integrata; non seleziona l'autenticazione SQL.
Il terminale funziona ma le richieste web falliscono Confronta il runtime PHP, le estensioni caricate, l'identità del processo, le variabili dell'ambiente e l'accesso alla rete. Non esporre una pagina pubblica phpinfo() con dettagli di configurazione.
Un'operazione successiva ha esito negativo con un handle chiuso Mantieni la connessione durante tutto il lavoro sulle istruzioni. Crea una nuova connessione dopo averne chiusa una; un vecchio handle non si riapre da solo.

Altri articoli di collegamento