Herstellen einer Verbindung mit einer Microsoft Azure SQL-Datenbank

PHP-Treiber herunterladen

Die SQLSRV- und PDO_SQLSRV-Treiber verbinden sich mit den folgenden Azure- und Fabric-SQL-Zielen mit einem vollständig qualifizierten Servernamen und den Verbindungsoptionen in Verbindungsoptionen. SQLSRV verwendet ein Optionsarray; PDO_SQLSRV nimmt einen Datenquellennamen (DSN), separate Zugangsdaten bei Bedarf und PDO-Attribute.

Ziel Servernamenformat Notes
Azure SQL-Datenbank <server>.database.windows.net
Verwaltete Azure SQL-Instanz Der öffentliche oder private Endpunkt Ihrer Instanz Erfordert Netzwerkverbindung über ein virtuelles Netzwerk, ein virtuelles privates Netzwerk (VPN) oder einen öffentlichen Endpunkt.
Azure Synapse Analytics (dedicated SQL pool in a workspace) <workspace>.sql.azuresynapse.net Unterstützte Transact-SQL (T-SQL)-Anweisungen unterscheiden sich von denen in SQL Server. Für unterstützte Syntax siehe die Synapse SQL-Dokumentation.
SQL-Datenbank in Microsoft Fabric Kopieren Sie den Server und die Datenbank aus den Einstellungen>Verbindungszeichenfolgen des Datenbankelements Nutze die SQL-Datenbankverbindung, nicht den SQL-Analytics-Endpunkt. Microsoft Entra-Authentifizierung ist erforderlich. Weitere Informationen finden Sie unter Herstellen einer Verbindung mit einer SQL-Datenbank in Fabric.
Lagerhaus in Microsoft Fabric Kopiere die SQL-Verbindungszeichenfolge des Warehouse aus dem Fabric-Portal Setze Database auf den Lagernamen und MultipleActiveResultSets auf false. Microsoft Entra-Authentifizierung ist erforderlich. Weitere Informationen finden Sie unter "Warehouse Connectivity".

Beide PHP-Erweiterungen aktivieren standardmäßig Multiple Active Result Sets (MARS). Warehouse unterstützt MARS nicht, also deaktiviere es explizit im SQLSRV-Options-Array oder PDO_SQLSRV DSN. SQL-Datenbanken in Fabric und Warehouse sind getrennte Produkte; gehen Sie nicht davon aus, dass eine von beiden unterstützte Funktion auch vom anderen unterstützt wird.

Richten Sie den Endpoint, die Identität und den PHP-Host ein

Ihr PHP-Prozess benötigt Netzwerkzugriff auf den SQL-Endpunkt, eine unterstützte Anmeldemöglichkeit und die Berechtigung, die ausgewählte Datenbank zu öffnen. Überprüfe jede Anforderung einzeln. Zum Beispiel gewährt das Öffnen eines Firewall-Ports keinen Datenbankzugriff.

  1. Installiere die PHP-Erweiterung und den Microsoft ODBC-Treiber auf dem Rechner oder Container, der PHP ausführt. Verifiziere die Erweiterung in jenem Prozess, nicht nur in einem Entwicklungsterminal. Weitere Informationen finden Sie unter Laden der Treiber.
  2. Kopieren Sie Server und Datenbank aus den Verbindungsdetails des Ziels. Fügen Sie kein HTTPS-URL-Schema hinzu. Verwenden Sie den vom Dienst bereitgestellten Hostnamen, damit die Zertifikatsvalidierung den vorgesehenen Endpunkt prüft. Ein öffentlicher Endpunkt der Azure SQL Managed Instance kann einen Nicht-Standard-Port enthalten; behalten Sie den bereitgestellten Port bei.
  3. Konfigurieren Sie den Netzwerkzugang des Dienstes für Ihren PHP-Host. Für einen privaten Endpunkt bestätigen Sie die Auflösung des privaten Namens und eine Route vom Anwendungsnetzwerk. Eine öffentliche Firewall-Regel bietet keine Route zu einer privaten Adresse.
  4. Wählen Sie die Identität, die vom PHP-Prozess verwendet wird. Für eine von Azure gehostete Anwendung aktivieren Sie ihre verwaltete Identität und ermitteln Sie, ob sie system- oder benutzerzugewiesen ist. Die Azure CLI-Anmeldung eines Entwicklers ist nicht die verwaltete Identität der Anwendung.
  5. Lassen Sie einen Datenbankadministrator dieser Identität Zugriff auf die ausgewählte Datenbank und die von der Anwendung benötigten Mindestberechtigungen gewähren. Überprüfen Sie für Warehouse auch den Zugriff auf Fabric-Elemente/-Arbeitsbereiche. Azure-Ressourcenverwaltungsberechtigungen gewähren von sich aus keine Berechtigung, Anwendungstabellen abzufragen.
  6. Legen Sie SQL_SERVER und SQL_DATABASE in der Konfiguration der Anwendung fest. Speichere kein Passwort für die Beispiele mit verwalteter Identität.

Die Beispiele verifizieren eine Verbindung, ohne Tabellen zu erstellen. Das Bestehen dieser Prüfung beweist nicht, dass die Identität dein Anwendungsschema lesen oder schreiben kann. Teste die tatsächlichen Operationen separat unter derselben Identität.

Verwenden Sie passwortlose Microsoft Entra-Authentifizierung

Verwenden Sie eine verwaltete Identität, wenn Ihre Hosting-Umgebung einen Managed-Identity-Endpunkt offenlegt und das SQL-Ziel dieser Identität Zugriff gewährt. Die folgenden vollständigen Programme verwenden eine systemzugeordnete verwaltete Identität. Sie sind keine Arbeitsstationsbeispiele. Führe sie auf dem konfigurierten Azure-Host aus, mit SQL_SERVER und SQL_DATABASE verfügbar für dessen PHP-Prozess.

Beide Programme deaktivieren MARS, daher ist auch die Verbindungseinstellung geeignet, wenn man Warehouse auswählt. Sie verwenden jeweils eine aktive Anweisung. Für Identitätseinrichtung und andere Authentifizierungsmodi siehe Verbinden mit Microsoft Entra-Authentifizierung.

Setze SQL_DATABASE auf den tatsächlichen Datenbanknamen. Jedes Programm erzeugt einen separaten Escaped-Wert für die Verbindung, indem es schließende geschweifte Klammern verdoppelt und den Namen mit Klammern einschließt. Durch das Escapen wird verhindert, dass Sonderzeichen im Datenbanknamen die Art und Weise ändern, wie der Treiber Verbindungseinstellungen liest. Die Programme behalten den ursprünglichen Namen bei, um das Ergebnis von DB_NAME()zu überprüfen.

SQLSRV

Speichere dieses Programm als connect-azure-sqlsrv.php, und führe php connect-azure-sqlsrv.php auf dem konfigurierten Host aus.

<?php
$server = getenv('SQL_SERVER');
$database = getenv('SQL_DATABASE');
if ($server === false || $server === '' || $database === false || $database === '') {
    throw new RuntimeException('Set SQL_SERVER and SQL_DATABASE.');
}
$databaseValue = '{' . str_replace('}', '}}', $database) . '}';

$conn = sqlsrv_connect($server, [
    'Database' => $databaseValue,
    'Authentication' => 'ActiveDirectoryMsi',
    'Encrypt' => true,
    'TrustServerCertificate' => false,
    'LoginTimeout' => 30,
    'MultipleActiveResultSets' => false,
    'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
    throw new RuntimeException(print_r(sqlsrv_errors(), true));
}

$stmt = null;
try {
    $stmt = sqlsrv_query(
        $conn,
        'SELECT DB_NAME() AS DatabaseName, CAST(1 AS int) AS Connected',
        [],
        ['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 !== ['DatabaseName' => $database, 'Connected' => 1]) {
        throw new RuntimeException('Unexpected database or connection result.');
    }
    echo 'Connected to ', $row['DatabaseName'], '.', PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

PDO_SQLSRV

Speichern Sie dieses separate Programm als connect-azure-pdo.php, und führen Sie php connect-azure-pdo.php auf dem konfigurierten Host aus. Dadurch wird PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE festgelegt, sodass das int-Ergebnis PHP int ist. Ohne sie gibt PDO_SQLSRV diese Spalte standardmäßig als Zeichenkette zurück. Die PDO-Codierung ist ein Attribut, nicht die SQLSRV-Option CharacterSet.

<?php
$server = getenv('SQL_SERVER');
$database = getenv('SQL_DATABASE');
if ($server === false || $server === '' || $database === false || $database === '') {
    throw new RuntimeException('Set SQL_SERVER and SQL_DATABASE.');
}
$databaseValue = '{' . str_replace('}', '}}', $database) . '}';
$pdo = new PDO(
    "sqlsrv:Server=$server;Database=$databaseValue;Authentication=ActiveDirectoryMsi;"
    . "Encrypt=true;TrustServerCertificate=false;LoginTimeout=30;"
    . "MultipleActiveResultSets=false",
    null,
    null,
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
        PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true,
    ]
);

$stmt = null;
try {
    $stmt = $pdo->prepare(
        'SELECT DB_NAME() AS DatabaseName, CAST(1 AS int) AS Connected',
        [PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 30]
    );
    $stmt->execute();
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row !== ['DatabaseName' => $database, 'Connected' => 1]) {
        throw new RuntimeException('Unexpected database or connection result.');
    }
    echo 'Connected to ', $row['DatabaseName'], '.', PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

Wenn SQL_DATABASEappdb ist, gibt jedes Programm Folgendes aus:

Connected to appdb.

ActiveDirectoryMsi verwendet nicht deine lokale Azure CLI-Anmeldung. Für lokale Entwicklung oder kontinuierliche Integration (CI) wählen Sie eine Authentifizierungsmethode, die von der PHP-Erweiterung und dem ODBC-Treiber unterstützt wird. Sie können ein Microsoft Entra-Zugriffstoken über eine Identitätsbibliothek abrufen und über AccessToken bereitstellen. Wenn du ein Token benutzt, solltest du Benutzername, Passwort und Authentication Einstellung weglassen. Legen Sie AccessToken im Array der SQLSRV-Verbindungsoptionen oder im PDO_SQLSRV-DSN fest. Halte Tokens aus dem Quellcode und den Protokollen heraus. Weitere Informationen finden Sie unter Connect using Microsoft Entra authentication.

ActiveDirectoryServicePrincipal verwendet eine Client-ID und ein Client-Geheimnis; es handelt sich nicht um passwortlose Authentifizierung. Wenn du es benutzt, lies das Secret aus der geschützten Anwendungskonfiguration. SQL-Authentifizierung ist nur für Zielsysteme eine Alternative, die sie unterstützen; weder SQL-Datenbanken in Fabric noch Warehouse unterstützen SQL-Authentifizierung.

Passen Sie die Authentifizierung an Ihre Umgebung an

Verwenden Sie für jede Verbindung einen Authentifizierungsmechanismus. Lassen Sie beim Wechsel zu Authentication keinen alten Benutzernamen, kein altes Passwort oder eine AccessToken-Einstellung bestehen.

Umwelt Configuration Verantwortung
Azure-Host mit einer systemzugewiesenen verwalteten Identität Setze Authentication auf ActiveDirectoryMsi. Gib keinen Benutzernamen oder kein Passwort an. ODBC erhält das Token vom Identitätsendpunkt des Hosts.
Azure Host mit einer benutzerzugewiesenen verwalteten Identität Setze Authentication auf ActiveDirectoryMsi. Geben Sie die ID der Identität über die SQLSRV-Option UID oder das PDO-Argument für den Benutzernamen an. Gib kein Passwort an. Die erforderliche ID hängt vom Hosting-Dienst ab. App Service und Container Instances verwenden die Client-ID; prüfen Sie die ODBC-Identitätsrichtlinien für andere Hosts.
Arbeitsstation oder CI mit einem externen Token-Anbieter Rufen Sie ein Token für den SQL-Dienst ab, und legen Sie dann AccessToken fest. Lassen Sie Benutzername, Passwort und Authentication Einstellung weg. Ihre Anwendung oder Identitätsbibliothek ruft das Token ab und aktualisiert es. Keine der beiden PHP-Erweiterungen verwendet automatisch deine Azure CLI-Anmeldung.
Service Principal mit einem Kundengeheimnis Setze Authentication auf ActiveDirectoryServicePrincipal. Für SQLSRV setze UID auf die Client-ID und PWD auf das Secret. Übergeben Sie für PDO die Client-ID und das Geheimnis als Argumente für Benutzername und Kennwort des Konstruktors. Schützen und rotieren Sie das Geheimnis. Diese Methode ist nicht passwortlos.
SQL-Login auf einem Ziel, das dies unterstützt SQLSRV verwendet UID/PWD; PDO verwendet Konstruktorargumente zwei und drei. Das Ziel überprüft die SQL-Zugangsdaten. Diese Option gilt für keines der beiden Fabric-Produkte.

Fordere ein Token für den SQL-Dienst an, nicht für das Azure-Ressourcenmanagement. Die Audience des Tokens identifiziert den Dienst, der ihn akzeptiert. Fordern Sie für die öffentliche Azure-Cloud den Bereich https://database.windows.net/.default von Ihrer Identitätsbibliothek an. Bestätigen Sie die passende Ressource für eine andere Cloud. Gib das Token als String an die PHP-Erweiterung weiter; wandele es nicht manuell in eine ODBC-Access-Token-Struktur um.

Ein Token kann ablaufen, während ein Worker weiterhin ausgeführt wird. Erhalten Sie vor dem Öffnen einer weiteren Verbindung ein gültiges Token und aktualisieren Sie die Token bei Bedarf bei langlebigen Arbeitern. Protokolliere niemals ein DSN, das ein Zugriffstoken enthält. Weitere Informationen zur ODBC-Authentifizierung finden Sie unter Verwendung von Microsoft Entra ID mit dem ODBC-Treiber.

Trennen von Verschlüsselungs- und Identitätsprüfungen

Encrypt=true fordert einen verschlüsselten Transport an. TrustServerCertificate=false erfordert die Validierung des Serverzertifikats, einschließlich seiner Identität. Microsoft Entra-Authentifizierung bestimmt, wer Ihre Anwendung ist; sie ersetzt die Server-Zertifikatsvalidierung nicht.

Verwenden Sie den vom SQL-Dienst bereitgestellten Endpunkt und pflegen Sie den Zertifikatsvertrauensspeicher des Client-Betriebssystems. Ersetzen Sie den Hostnamen nicht durch eine IP-Adresse, um ein Problem bei der Namensauflösung zu umgehen. Bei einem privaten Endpunkt sollten Sie die Namensauflösung und das Routing korrigieren und dabei den erwarteten Verbindungsnamen des Dienstes beibehalten.

LoginTimeout begrenzt den Verbindungsaufbau. QueryTimeout für SQLSRV und PDO::SQLSRV_ATTR_QUERY_TIMEOUT für PDO_SQLSRV gelten für die Ausführung von Anweisungen. Das Erhöhen eines Abfragetimeouts repariert keinen fehlenden Endpunkt für verwaltete Identitäten oder einen falschen Datenbankbenutzer.

Problembehandlung nach Fehlerphase

Fehlerphase Was soll überprüft werden?
PHP kann die Erweiterung nicht laden Bestätigen Sie die Laufzeitversion, die Architektur, den Erweiterungsbuild, die ODBC-Installation und die vom Anwendungsprozess verwendete php.ini.
Timeout der TCP-Verbindung (Transmission Control Protocol) Überprüfen Sie den kopierten Endpunkt und Port, die Namensauflösung, die Firewall-Regeln, das virtuelle Netzwerkrouting und die Konfiguration des privaten Endpunkts vom PHP-Host.
Fehler bei der Zertifikatüberprüfung Überprüfen Sie den Endpunktnamen, die Zertifikatskette und den Client Trust Store. Lassen Sie die Zertifikatsvalidierung aktiviert.
Verwaltete Identität kann kein Token abrufen Bestätigen Sie, dass die Identität auf diesem Host aktiviert ist und dass sein Identitätsendpunkt verfügbar ist. Testen Sie ActiveDirectoryMsi nicht auf einem gewöhnlichen Laptop, und erwarten Sie nicht, dass die Azure CLI-Anmeldung dies erfüllt.
Die Token-Authentifizierung scheitert Überprüfen Sie den beabsichtigten Dienst, den Ablauf, den Mandanten und die Identität des Tokens. Bestätigen Sie den Datenbankzugriff für diese Identität. Entfernen Sie alle Einstellungen für Benutzername, Kennwort und Authentication.
Der Login gelingt, aber die ausgewählte Datenbank kann nicht geöffnet werden Bestätigen Sie den Datenbanknamen und dass der Administrator die beabsichtigte Identität erstellt oder ihr Zugriff gewährt hat.
Verbindung öffnet sich, aber eine Anwendungsanfrage schlägt fehl Überprüfen Sie die Objektberechtigungen und die vom Ziel unterstützten T-SQL-Funktionen. Der Verbindungstest stellt keinen Anwendungsschema-Zugriff her.
Warehouse lehnt Verbindungseinstellungen ab Legen Sie MultipleActiveResultSets im SQLSRV-Optionen-Array oder PDO-DSN auf false fest, und verwenden Sie die Microsoft Entra-Authentifizierung.

SQLSRV gibt false zurück und stellt eine Fehlersammlung über sqlsrv_errors() bereit. Die PDO-Konstruktion löst PDOException aus. Die Beispiele aktivieren auch Ausnahmen für Anweisungsfehler. Erfassen Sie sofort Diagnosen in eingeschränkten Logs und halten Sie SQLSRV-Warnungen von Fehlern getrennt. Geben Sie keine unformatierten Diagnosen, Token oder Verbindungsdetails an einen Browser zurück.

Planen für unterbrochene Verbindungen

Ein Dienst kann eine inaktive Sitzung trennen oder einen Vorgang während Wartung oder Failover unterbrechen. ODBC-Resilienz bei Verbindungsleerlauf und Anwendungswiederholungen lösen unterschiedliche Probleme. Informationen zu Wiederholungsschlüsselwörtern und einem kontrollierten Trennungstest finden Sie unter Resilienz bei Verbindungsleerlauf.

Wiederholen Sie einen Schreibvorgang nicht nur, weil der Client seine Verbindung verloren hat. Der Server hat möglicherweise einen Commit ausgeführt, bevor die Antwort verloren ging. Verwenden Sie eine anwendungsspezifische Wiederholungsrichtlinie und eine Möglichkeit, doppelte Arbeit zu erkennen. Geben Sie Anweisungen und Verbindungshandles frei, wenn die Anforderung oder der Auftrag abgeschlossen ist, einschließlich Fehlerpfaden. Für Lebenszyklus und Pooling-Verhalten siehe Verbindung mit dem Server herstellen.