Verbindung zum Server

PHP-Treiber herunterladen

Verwenden Sie diese Anleitung, um eine Verbindung zu öffnen, überprüfen Sie die erhaltenen Werte von PHP und lösen Sie die Verbindung, 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

  1. Installiere eine unterstützte PHP-Laufzeit und einen Microsoft ODBC-Treiber und lade die PHP-Erweiterung, die du verwenden möchtest.
  2. Schau dir den PHP-Prozess an, der deine Bewerbung ausführt. Führe php --ini aus, um die Kommandozeilenkonfiguration zu finden und php -m die geladenen Erweiterungen aufzulisten. SQLSRV erfordert sqlsrv. PDO_SQLSRV benötigt PDO und pdo_sqlsrv. Ein Webserver kann ein anderes php.iniRuntime- und Runtime-Konto von deinem Terminal verwenden.
  3. 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.
  4. 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. Mache keine Passwortdatei und drucke 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. Behalte die Verbindungsschlüsselwörter unter Anwendungskontrolle.

Speichere 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 dich an sqlsrv_* Funktionen weitergeben. Überprüfe, bevor false du einen der Griffe benutzt. Sofort nach einem Fehler abrufen sqlsrv_errors() , 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 in PHP null; das bedeutet nicht, dass die Zeile nicht vorhanden ist. Verwenden Sie === diese Werte beim Unterscheiden dieser Werte.

Öffnen, Abfrage und schließen mit PDO_SQLSRV

Speichere dieses separate Programm als connect-pdo.php, und führe php connect-pdo.php es in 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 Datenbankvorgangfehlern PDOException ausgelöst wird. Die Verbindungskonstruktion löst bei einem Fehlschlag unabhängig von dieser Einstellung eine Ausnahme 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 Kommandozeilenprogramme lassen Fehler die Ausführung stoppen. Fangen Sie in einer Webanwendung Ausnahmen in dem Code ab, der die Anfrage verarbeitet. Protokolliere diagnostische Details in geschützten Protokollen und gib eine generische Fehlerantwort zurück. Senden sqlsrv_errors()Sie keine , 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 UID SQLSRV und PWD in seinem Verbindungsoptions-Array. 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 AccessToken SQLSRV das Options-Array auf, während PDO_SQLSRV es im DSN verwendet.

Wenn du Benutzername, Passwort Authenticationund AccessTokenauslässt, fordern beide Treiber eine integrierte Authentifizierung von ODBC an, indem sie .Trusted_Connection=Yes 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 Sie die Verbindung und ihre Statements

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 Verhaltensverantwortlicher
Endpoint und Datenbank Server-Argument und Database Option. Server und Database DSN-Schlüsselwörter. ODBC und das SQL-Ziel.
SQL-Anmeldeinformationen UID und Optionen PWD . 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 Zugangsdaten 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 der Zertifikatsvertrauenskonfiguration des Betriebssystems.
Verbindungs-Einrichtungs-Timeout LoginTimeout Verbindungseinstellung, in Sekunden. LoginTimeout DSN-Schlüsselwort, in Sekunden. ODBC. Es ist nicht das Timeout für die Ausfü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.
Datums- und Uhrzeitobjekte Für ReturnDatesAsStrings ist false standardmäßig festgelegt, sodass Datums- und Uhrzeitspalten DateTime-Objekte zurückgeben. Standardmäßig Zeichenketten; verwenden Sie PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, um Objekte anzufordern. PHP-Erweiterungs-Typkonvertierung.
MARS (Multiple Active Result Sets, mehrere aktive Resultsets) MultipleActiveResultSets Verbindungsoption. MultipleActiveResultSets DSN-Schlüsselwort. ODBC und Unterstützung für Zielsysteme. 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. Platziere keine CharacterSet, QueryTimeout oder PDO:: Konstantennamen in einem PDO-DSN.

Lebensdauer der Verbindung verwalten

Stelle eine Verbindung her, wenn eine Anfrage oder ein Job Datenbankarbeit benötigt. Verwenden Sie es während dieser Anfrage oder Aufgabe erneut und geben es dann frei, wenn Sie damit fertig sind. Nicht für jede Zeile verbinden und trennen. Bei einem lang laufenden Worker sollten Sie Anweisungen freigeben und jede Transaktion abschließen, bevor Sie den nächsten Auftrag annehmen.

SQLSRV schließt zugehörige Anweisungen, wenn die Verbindung geschlossen wird. Das explizite frühzeitige Freigeben von Statements 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. Gib auch diese Verweise frei. closeCursor() gibt ausstehende Ergebnisse frei, damit das Statement wiederverwendet werden kann; es ist keine Verbindungsschließungsmethode.

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, kein Commit. 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 Connection pooling.

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 Details ihrer Datenbankverbindung und die Microsoft Entra-Authentifizierung. Ersetzen Sie nicht den SQL-Analytics-Endpunkt.
Lagerhaus in Microsoft Fabric Verwenden Sie den 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 Startwarnungen.
PDO meldet could not find driver Bestätigen Sie, dass pdo_sqlsrv in diesem Prozess geladen ist und sqlsrv in PDO::getAvailableDrivers() erscheint.
ODBC-Treiber wurde nicht gefunden Installiere den Microsoft ODBC-Treiber und überprüfe dessen Registrierung und Architektur. Die Installation einer PHP-Erweiterung installiert ODBC nicht.
Verbindungsauszeit 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 fehlschlägt Installiere die korrekte Vertrauenskette und verwende den Hostnamen des Zertifikats. Behandle 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 Zugangsdaten fordert integrierte Authentifizierung an; es wählt keine SQL-Authentifizierung aus.
Das Terminal gelingt, 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ätere Operation schlägt an einem geschlossenen Griff fehl Behalten Sie die Verbindung während aller Statements aufrecht. Erstelle eine neue Verbindung nach dem Schließen einer Verbindung; ein alter Handle öffnet sich nicht von selbst wieder.

Weitere Artikel zu Verbindungen