Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Verwenden Sie diese Anleitung, um eine Verbindung zu öffnen, die von PHP erhaltenen Werte zu prüfen und die Verbindung freizugeben, wenn die Arbeit abgeschlossen ist. Die Programme verwenden SQL Server-Authentifizierung für eine lokale oder entfernte SQL Server-Testdatenbank. Für passwortlose Azure- und Fabric-Verbindungen verwenden Sie Connect to Azure SQL and Fabric SQL.
SQLSRV akzeptiert einen Servernamen und ein assoziatives Array von Verbindungsoptionen. PDO_SQLSRV implementiert PHP Data Objects (PDO) und akzeptiert einen Datenquellennamen-(DSN)-String, separate Zugangsargumente und ein Array von PDO-Attributen. Beide verwenden den Microsoft ODBC-Treiber für SQL Server. Eine Verbindung, die mit einer API funktioniert, macht die Optionsnamen oder PHP-Typen der anderen API nicht austauschbar.
Bevor du dich verbindest
- Installieren Sie eine unterstützte PHP-Laufzeit und einen Microsoft ODBC-Treiber und laden Sie die PHP-Erweiterung, die Sie verwenden möchten.
- Überprüfen Sie den PHP-Prozess, der Ihre Anwendung ausführt. Führe
php --iniaus, um die Kommandozeilenkonfiguration zu finden undphp -mdie geladenen Erweiterungen aufzulisten. SQLSRV erfordertsqlsrv. PDO_SQLSRV benötigtPDOundpdo_sqlsrv. Ein Webserver kann ein anderesphp.ini, Laufzeit und Konto von Ihrem Terminal verwenden. - Erhalten Sie die Serveradresse, den Datenbanknamen und eine Identität mit Berechtigung zur Verbindung. Ein Datenbank-Login gewährt nicht automatisch Zugriff auf jede Tabelle.
- Konfigurieren Sie den Netzwerkzugang und ein vertrauenswürdiges Serverzertifikat. Diese Programme fordern ausdrücklich Verschlüsselung und Zertifikatsvalidierung an. Verbinden Sie sich über den Hostnamen des Zertifikats, anstatt eine IP-Adresse zu verwenden, die das Zertifikat nicht abdeckt.
Stellen Sie diese Variablen in der Umgebung des PHP-Prozesses ein, indem Sie Ihre Shell, Ihr Entwicklungstool oder Ihre Hosting-Konfiguration verwenden. Übergeben Sie keine Passwortdatei und geben Sie die Umgebung nicht aus.
| Variable | Value |
|---|---|
SQL_SERVER |
Der Server-Hostname, optional mit tcp: vorangestellt und von ,<port> gefolgt. |
SQL_DATABASE |
Eine bestehende Datenbank, auf die Ihr Login zugreifen kann. |
SQL_USER |
Eine SQL Server-Anmeldung. |
SQL_PASSWORD |
Das Passwort dieses Logins, das über eine geschützte Konfiguration bereitgestellt wird. |
Lesen Sie Server- und Datenbankeinstellungen aus der vertrauenswürdigen Anwendungskonfiguration, nicht aus Webanforderungsparametern. Das PDO-Beispiel setzt diese Einstellungen in ein DSN. Behalten Sie die Verbindungsschlüsselwörter unter Anwendungskontrolle.
Speichern Sie den tatsächlichen Datenbanknamen, Benutzernamen und das Passwort in den Umgebungsvariablen, ohne selbst geschweifte Klammern hinzuzufügen oder zu verdoppeln. Beide PHP-Erweiterungen erfordern ODBC-ähnliches Escape, selbst für SQLSRV-Array-Optionen und PDO-Konstruktorargumente: jede schließende geschweifte Klammer verdoppeln und den Wert in geschweifte Klammern einschließen. Jedes Programm macht dies einmal, bevor es diese Werte an den Treiber weitergibt. Die äußeren Klammern bewahren die wörtlichen Klammern am Anfang und Ende eines Wertes und verhindern, dass Semikolons im Datenbanknamen die PDO-DSN-Einstellungen trennen. Dieses Escapen ist getrennt von Transact-SQL (T-SQL)-Parameterbindung.
Öffnen, abfragen und schließen mit SQLSRV
Speichere dieses Programm als connect-sqlsrv.php, und führe php connect-sqlsrv.php aus. Es führt eine T-SQL-Abfrage aus, ohne Tabellen zu erstellen oder Daten zu ändern.
CharacterSet wählt UTF-8 für Zeichendaten aus; es ändert weder die Spaltentypen noch die Sortierung der Datenbank.
<?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);
}
Erwartete Ausgabe:
{"Value":42,"Label":"caf\u00e9","Missing":null}
Die Verbindung und die Anweisung sind PHP-Ressourcen, die Sie an sqlsrv_*-Funktionen weitergeben. Überprüfen Sie auf false, bevor Sie einen der Handle benutzen. Sofort nach einem Fehler sqlsrv_errors() abrufen, da ein späterer SQLSRV-Aufruf die Fehlersammlung ersetzen kann.
SQLSRV_FETCH_ASSOC gibt ein assoziatives Array mit Spaltennamen als Schlüssel zurück.
SQLSRV_FETCH_NUMERIC gibt null-basierte numerische Schlüssel zurück; der Standard SQLSRV_FETCH_BOTH enthält beide Formen. Für sqlsrv_fetch_array() bedeutet null keine Zeilen mehr und false bedeutet einen Fehler. Ein SQL-NULL innerhalb einer Zeile entspricht PHP null; das bedeutet nicht, dass die Zeile nicht vorhanden ist. Verwenden Sie === beim Unterscheiden dieser Werte.
Öffnen, abfragen und schließen mit PDO_SQLSRV
Speichern Sie dieses separate Programm als connect-pdo.php und führen Sie php connect-pdo.php mit derselben Umgebung aus.
sqlsrv: wählt PDO_SQLSRV aus, nicht den generischen PDO_ODBC-Treiber von PHP.
<?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;
}
Erwartete Ausgabe:
{"Value":"42","Label":"caf\u00e9","Missing":null}
PDO_SQLSRV gibt diese int-Spalte standardmäßig als PHP-String zurück. Um PHP-numerische Typen für unterstützte numerische Spalten anzufordern, setzen Sie PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE auf true. Verwenden Sie keinen PHP-Cast wahllos für Dezimalwerte; eine Gleitkomma-Umwandlung kann zu Präzisionsverlust führen.
PDO-Attribute sind Einstellungen auf dem Verbindungs- oder Statement-Objekt.
PDO::ATTR_ERRMODE mit PDO::ERRMODE_EXCEPTION bewirkt, dass bei Datenbankvorgangsfehlern PDOException ausgelöst wird. Die Verbindungskonstruktion löst bei einem Fehler unabhängig von dieser Einstellung aus.
PDO::FETCH_ASSOC gibt benannte Schlüssel, PDO::FETCH_NUM nullbasierte numerische Schlüssel und PDO::FETCH_BOTH beide.
fetch() gibt false am Ende des Ergebnisses zurück; SQL-NULL-Werte innerhalb einer Zeile bleiben PHP-null.
Diese Befehlszeilenprogramme lassen Fehler die Ausführung stoppen. Fangen Sie in einer Webanwendung Ausnahmen in dem Code ab, der die Anfrage verarbeitet. Sie protokollieren diagnostischen Details in geschützten Protokollen und geben eine generische Fehlerantwort zurück. Senden Sie keine sqlsrv_errors(), Ausnahmespuren, Verbindungszeichenketten oder Token an einen Browser.
Auswählen eines Authentifizierungsmodus
| Modus | Verwendung für | Siehe |
|---|---|---|
| SQL Server Authentifizierung | On-premises SQL Server, Container und Azure SQL, wenn Microsoft Entra ID nicht verfügbar ist | Verbinden Sie sich mit SQL Server-Authentifizierung |
| Integrierte Authentifizierung (kein Benutzername oder Passwort in den Verbindungseinstellungen) | Windows-Identitäten oder für Kerberos konfigurierte Linux/macOS-Clients | Verbinden Sie sich mit Windows-Authentifizierung |
Microsoft Entra ID (Authenticationoder AccessToken Schlüsselwort) |
Azure SQL und Fabric SQL Targets konfiguriert für Microsoft Entra ID | Herstellen einer Verbindung mit der Microsoft Entra-Authentifizierung |
Für SQL-Authentifizierung nimmt SQLSRV UID und PWD in sein Verbindungsoptionsarray auf. PDO_SQLSRV nimmt Benutzername und Passwort als zweite und dritte Argumente für new PDO(), nicht als DSN-Schlüsselwörter. Für ein Zugriffstoken nimmt SQLSRV AccessToken in das Optionsarray auf, während PDO_SQLSRV es im DSN verwendet.
Wenn Sie Benutzernamen, Passwort, Authentication und AccessTokenauslassen, fordern beide Treiber eine integrierte Authentifizierung von ODBC an, indem sie Trusted_Connection=Yes verwenden. Unter Linux und macOS erfordert diese Anfrage ein gültiges Kerberos-Ticket und eine integrierte ODBC-Authentifizierungskonfiguration. Es gewährt einem beliebigen lokalen Konto keinen Zugriff auf einen entfernten Server.
Konfigurieren der Verbindung und seiner Anweisungen
Die Verbindungseinstellungen gelten für die Sitzung, die du öffnest. Statement-Einstellungen gelten für eine bestimmte Abfrage. Setze Timeouts und Ergebnistypen explizit, wenn deine Anwendung andere Werte als die Standardwerte benötigt.
| Purpose | SQLSRV | PDO_SQLSRV | Verhaltensbesitzer |
|---|---|---|---|
| Endpoint und Datenbank | Server-Argument und Database Option. |
Server und Database DSN-Schlüsselwörter. |
ODBC und das SQL-Ziel. |
| SQL-Anmeldeinformationen |
UID und PWD-Optionen. |
Argumente für Benutzername und Passwort des Konstruktors. | Verwaltung von Erweiterungszugangsdaten und Server-Authentifizierung. |
| Microsoft Entra-Authentifizierung |
Authentication Option oder die separate AccessToken Option. |
Authentication oder AccessToken DSN-Schlüsselwort, wobei die Anmeldeinformation für ein externes Token ausgelassen wurden. |
ODBC-Authentifizierung; die Anwendung erhält externe Token. |
| Encryption |
Encrypt => true. |
Encrypt=true im DSN. |
ODBC Transportsicherheit. |
| Zertifikatüberprüfung |
TrustServerCertificate => false. |
TrustServerCertificate=false im DSN. |
ODBC und die Zertifikatsvertrauenskonfiguration des Betriebssystems. |
| Timeout der Verbindungsherstellung |
LoginTimeout Verbindungseinstellung, in Sekunden. |
LoginTimeout DSN-Schlüsselwort, in Sekunden. |
ODBC. Es ist nicht das Timeout für die Anweisungsausführung. |
| Zeitüberschreitung bei der Abfrage |
QueryTimeout Aussageoption, in Sekunden. |
PDO::SQLSRV_ATTR_QUERY_TIMEOUT, auf der Verbindung oder Anweisung. |
Erweiterungs- und ODBC-Anweisungshandhabung. |
| Zeichencodierung |
CharacterSet => 'UTF-8' Verbindungsoption. |
PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8. |
Konvertierung von PHP-Erweiterungen. PDO_SQLSRV ist standardmäßig UTF-8; SQLSRV setzt standardmäßig die Systemcodierung ein. |
| Datum- und Uhrzeitobjekte |
ReturnDatesAsStrings ist standardmäßig false, sodass Datum- und Uhrzeitspalten DateTime-Objekte zurückgeben. |
Standardmäßig Zeichenketten; verwenden Sie PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, um Objekte anzufordern. |
PHP-Erweiterungstypkonvertierung. |
| MARS (Multiple Active Result Sets, mehrere aktive Resultsets) |
MultipleActiveResultSets Verbindungsoption. |
MultipleActiveResultSets DSN-Schlüsselwort. |
ODBC und Zielunterstützung. Beide Erweiterungen aktivieren diese Funktion standardmäßig; deaktivieren Sie diese Funktion für Warehouse in Fabric. |
| Leerlaufrückgewinnung |
ConnectRetryCount und ConnectRetryInterval Verbindungsoptionen. |
Die gleichen DSN-Schlüsselwörter. | ODBC. Sie wiederholen keine beliebigen Anwendungsvorgänge. |
Für die vollständige Liste der Schlüsselwörter, erlaubten Werte und Standardwerte siehe Verbindungsoptionen. Platzieren Sie keine CharacterSet, QueryTimeout oder PDO:: Konstantennamen in einem PDO-DSN.
Verbindungsdauer verwalten
Öffnen Sie eine Verbindung, wenn eine Anforderung oder ein Einzelvorgang Datenbankarbeit benötigt. Verwenden Sie es während dieser Anforderung oder diesem Einzelvorgang erneut und geben es dann frei, wenn Sie damit fertig sind. Nicht für jede Zeile verbinden und trennen. Bei einem Vorgang mit langer Ausführungsdauer geben Sie Anweisungen frei und schließen Sie jede Transaktion ab, bevor Sie den nächsten Einzelvorgang annehmen.
SQLSRV schließt zugehörige Anweisungen, wenn Sie dessen Verbindung schließen. Das explizite frühzeitige Freigeben von Anweisungen setzt Ressourcen frei, ohne die Verbindung zu beenden. Bei PDO entfernt das Zuweisen $pdo = null nur die Referenz dieser Variablen. Eine PDOStatement oder eine andere Variable kann die Verbindung weiterhin behalten. Geben Sie auch diese Verweise frei.
closeCursor() gibt ausstehende Ergebnisse frei, damit die Anweisung wiederverwendet werden kann; es ist keine Methode zur Verbindungsschließung.
Beide APIs starten im Autocommit-Modus: Eine erfolgreiche Anweisung wird ohne separaten Anwendungscommit committiert, es sei denn, du startest eine Transaktion. Für eine Gruppe von Schreibvorgängen, die gemeinsam erfolgreich sein oder scheitern müssen, verwenden Sie sqlsrv_begin_transaction() oder $pdo->beginTransaction() und führen Sie dann explizit Commit oder Rollback aus. Beim Schließen einer Verbindung mit einer ausstehenden Transaktion wird ein Rollback versucht, keine Übernahme. Verlassen Sie sich nicht darauf, dass Shutdown Cleanup Ihre Transaktionsrichtlinie umsetzt. Für vollständige Beispiele siehe Transaktionen ausführen.
Das Freigeben eines PHP-Verbindungshandles schließt nicht zwangsläufig die physische Netzwerkverbindung. ODBC-Pooling kann es für die Wiederverwendung behalten. Pooling ist kein Grund, PHP-Ressourcen unbegrenzt zu behalten, und PDO_SQLSRV unterstützt PDO::ATTR_PERSISTENT => true nicht. Informationen zur plattformspezifischen Pooling-Konfiguration finden Sie unter Verbindungspooling.
Wenden Sie den Leitfaden auf Ihr SQL-Ziel an
Die Handle-, Fetch- und Cleanup-Muster gelten für beide Erweiterungen auf unterstützten SQL-Zielen. Verbindungsendepunkte, Authentifizierung, Netzwerkzugang und SQL-Funktionen variieren.
| Ziel | Anpassung |
|---|---|
| SQL Server | Die Programme verwenden ein SQL-Login. Integrierte Authentifizierung ist eine weitere Option, wenn Sie die PHP-Prozessidentität konfigurieren. |
| Azure SQL-Datenbank | Verwenden Sie den Hostnamen des logischen Servers und die explizite Datenbank. Bevorzuge Microsoft Entra-Authentifizierung statt der SQL-Zugangsdaten in diesen Programmen. |
| Verwaltete Azure SQL-Instanz | Verwenden Sie den Instanz-Endpunkt und dessen Netzwerkzugriffsanforderungen. Gehen Sie nicht davon aus, dass ein privater Endpunkt von Ihrem Arbeitsplatz aus erreichbar ist. |
| Azure Synapse Analytics | Verwenden Sie den SQL-Pool-Endpunkt und prüfen Sie dessen T-SQL-Unterstützung, bevor Sie Abfragen anpassen, die Objekte erstellen oder verändern. |
| SQL-Datenbank in Microsoft Fabric | Verwenden Sie die Verbindungsdetails der Datenbank und Microsoft Entra-Authentifizierung. Ersetzen Sie nicht den SQL-Analytics-Endpunkt. |
| Lagerhaus in Microsoft Fabric | Verwenden Sie dessen Warehouse-Endpunkt und die Datenbank, Microsoft Entra-Authentifizierung und MultipleActiveResultSets=false. |
Für dienstspezifische Einrichtung siehe Azure- und Fabric-Verbindungen.
Beheben von Verbindungsproblemen
Beginne mit dem Schritt, der fehlgeschlagen ist. Eine erfolgreiche Überprüfung des Transmission Control Protocol (TCP) beweist nicht, dass die Authentifizierung oder Zertifikatsvalidierung erfolgreich war.
| Symptom | Prüfen |
|---|---|
Call to undefined function sqlsrv_connect() |
Der ausführende PHP-Prozess hat sqlsrv nicht geladen. Überprüfen Sie php.ini und die Startup-Warnungen. |
PDO meldet could not find driver |
Bestätigen Sie, dass pdo_sqlsrv in diesem Prozess geladen ist und sqlsrv in PDO::getAvailableDrivers() erscheint. |
| Der ODBC-Treiber kann nicht gefunden werden | Installiere den Microsoft ODBC-Treiber und überprüfe dessen Registrierung und Architektur. Die Installation einer PHP-Erweiterung installiert ODBC nicht. |
| Verbindungs-Timeout oder Server wurde nicht gefunden | Überprüfen Sie den Servernamen, den Port, die Namensauflösung, das Routing, die Firewall-Regeln und ob SQL Server auf TCP lauscht. |
| Die Validierung der Zertifikatskette oder des Hostnamens schlägt fehl | Installiere die korrekte Vertrauenskette und verwende den Hostnamen des Zertifikats. Behandeln Sie TrustServerCertificate=true nicht als Fix für die Produktion. |
| Login schlägt fehl oder die Datenbank kann nicht geöffnet werden | Überprüfen Sie den Authentifizierungsmodus, den Datenbanknamen, Login/Benutzerzuordnung und Berechtigungen. Das Weglassen von Anmeldeinformation fordert integrierte Authentifizierung an; es wählt keine SQL-Authentifizierung aus. |
| Das Terminal ist erfolgreich aber Webanfragen schlagen fehl | Vergleichen Sie die PHP-Laufzeit, geladene Erweiterungen, Prozessidentität, Umgebungsvariablen und Netzwerkzugang. Stellen Sie keine öffentliche phpinfo() Seite mit Konfigurationsdetails öffentlich bereit. |
| Eine späterer Vorgang schlägt an einem abgeschlossenen Handle fehl | Halten Sie die Verbindung während aller Anweisungen aufrecht. Erstelle eine neue Verbindung nach dem Schließen einer Verbindung; ein alter Handle öffnet sich nicht von selbst wieder. |
Sonstige Verbindungsartikel
- Verbinden Sie sich an einem bestimmten Port
- Verbindungsoptionen
- Pooling von Verbindungen
- Deaktivieren Sie mehrere aktive Ergebnissätze (MARS)
- Unterstützung für LocalDB
- Unterstützung für Hochverfügbarkeit und Notfallwiederherstellung
- Herstellen einer Verbindung mit einer Microsoft Azure SQL-Datenbank
- Widerstandsfähigkeit der Leerlaufverbindung