Microsoft Azure SQL Database への接続

PHP ドライバーのダウンロード

SQLSRVおよびPDO_SQLSRVドライバは、完全修飾サーバー名とConnection optionsの接続オプションを使用して、以下のAzureおよびFabric SQLターゲットに接続します。 SQLSRVはオプション配列を受け取ります。PDO_SQLSRVはデータソース名(DSN)、必要に応じて別々の認証情報引数、そしてPDO属性を受け取ります。

目標 サーバー名フォーム 備考
Azure SQL Database <server>.database.windows.net
Azure SQL Managed Instance あなたのインスタンスのパブリックエンドポイントかプライベートエンドポイントか 仮想ネットワーク、仮想プライベートネットワーク(VPN)、またはパブリックエンドポイントを介したネットワーク接続が必要です。
Azure Synapse Analytics (ワークスペース内の専用SQL プール) <workspace>.sql.azuresynapse.net サポートされた Transact-SQL(T-SQL)文はSQL Serverと異なります。 サポートされている構文についてはSynapse SQLドキュメントを参照してください。
Microsoft Fabric の SQL データベース データベース項目の設定>接続文字列からサーバーとデータベースをコピーします SQL データベース接続を使用し、その SQL アナリティクス エンドポイントは使用しないでください。 Microsoft Entra認証が必要です。 詳細については、Fabric SQL データベースへの接続に関する記事を参照してください。
Microsoft Fabric のウェアハウス FabricポータルからウェアハウスのSQL 接続文字列をコピーします Databaseを倉庫名に設定し、MultipleActiveResultSetsをfalseに設定します。 Microsoft Entra認証が必要です。 詳細については、「 ウェアハウス接続」を参照してください。

両方のPHP拡張はデフォルトで複数のアクティブ結果セット(MARS)を有効にしています。 WarehouseはMARSをサポートしていないので、SQLSRVのオプション配列またはPDO_SQLSRVのDSNで明示的に無効にしてください。 FabricとWarehouseのSQLデータベースは別々の製品です。一方でサポートされている機能がもう一方でサポートされていると仮定しないでください。

エンドポイント、アイデンティティ、PHPホストを準備します

PHPプロセスにはSQLエンドポイントへのネットワークアクセス、対応されたサインイン方法、選択したデータベースを開く権限が必要です。 各要件を個別に確認してください。 例えば、ファイアウォールポートを開けてもデータベースへのアクセスは許されません。

  1. PHPを動かすマシンやコンテナにPHP拡張とMicrosoft ODBCドライバーをインストールしてください。 拡張機能は開発端末だけでなく、その処理で確認してください。 詳細は ドライバーを読み込む をご覧ください。
  2. ターゲットの接続情報からサーバーとデータベースをコピーします。 HTTPSのURLスキームは含めないでください。 サービス提供のホスト名を使うことで、証明書の検証で意図したエンドポイントを確認できます。 Azure SQL Managed Instanceのパブリックエンドポイントは、非デフォルトポートを含めることができます;提供されたポートを保持してください。
  3. PHP ホストのネットワーク アクセスを設定してください。 プライベートエンドポイントの場合は、プライベートネーム解決とアプリケーションネットワークからのルートを確認してください。 パブリックファイアウォールルールはプライベートアドレスへのルートを提供しません。
  4. PHPプロセスで使用される実行ユーザーを選択します。 Azureホスト型アプリケーションの場合、マネージドIDを有効にし、システム割り当てかユーザー割り当てかを特定します。 開発者のAzure CLIサインインはアプリケーションのマネージドIDではありません。
  5. データベース管理者に、その ID に対して、選択したデータベースへのアクセス権とアプリケーションに必要な最小限の権限を付与してもらいます。 Warehouseについては、Fabricのアイテムやワークスペースへのアクセスも確認してください。 Azureのリソース管理権限自体は、アプリケーションテーブルのクエリ権限を付与するものではありません。
  6. アプリケーションの設定で SQL_SERVER と SQL_DATABASE を設定します。 管理型IDの例ではパスワードを保存しないでください。

これらの例はテーブルを作らずに接続を検証します。 このチェックに合格しても、そのIDがアプリケーションのスキーマを読み書きできるとは限りません。 実際の操作は同じアイデンティティで別々にテストしてください。

パスワードレスの Microsoft Entra 認証を使用する

ホスト環境がマネージド アイデンティティ エンドポイントを公開し、SQL ターゲットがその ID にアクセス権を付与する場合は、マネージド ID を使用します。 以下の完全なプログラムは、システムに割り当てられた管理型IDを使用しています。 それらはワークステーションの例ではありません。 それらを設定されたAzureホスト上で実行し、そのPHPプロセスではSQL_SERVERとSQL_DATABASEが利用可能です。

両プログラムともMARSを無効にするため、Warehouse選択時の接続設定も適しています。 彼らは一度に一つの有効なステートメントを使っています。 ID設定やその他の認証モードについては、「Microsoft Entra認証を使った接続」を参照してください。

SQL_DATABASEを実際のデータベース名に設定してください。 各プログラムは、閉じ括弧を倍増させて名前を括弧で囲むことで、接続用の別々のエスケープされた値を作成します。 エスケープはデータベース名の特殊文字がドライバーの接続設定の読み取り方を変えるのを防ぎます。 プログラムは DB_NAME()の結果を確認するために元の名前を保持しています。

SQLSRV

このプログラムを connect-azure-sqlsrv.phpとして保存し、設定されたホスト上で php connect-azure-sqlsrv.php 実行してください。

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

この別プログラムを connect-azure-pdo.phpとして保存し、設定されたホスト上で php connect-azure-pdo.php 実行してください。 PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPEを設定すると、intの結果はPHP intになります。 それがなければ、PDO_SQLSRVはデフォルトでこの列を文字列として返します。 PDOエンコーディングは属性であり、SQLSRVの 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;
}

SQL_DATABASEがappdbの場合、各プログラムは次のように出力します:

Connected to appdb.

ActiveDirectoryMsiお使いのローカルのAzure CLIサインインを使いません。 ローカル開発や継続的統合(CI)では、PHP拡張とODBCドライバーでサポートされている認証方法を選択してください。 アイデンティティ ライブラリを通じて Microsoft Entra アクセス トークンを取得し、AccessToken で指定できます。 トークンを使う際は、ユーザー名、パスワード、およびAuthentication設定を省いてください。 SQLSRV接続オプション配列またはPDO_SQLSRV DSNで AccessToken を設定してください。 トークンはソースコードやログから排除しましょう。 詳細については、「 Microsoft Entra 認証を使用した接続を参照してください。

ActiveDirectoryServicePrincipal クライアントIDとクライアントシークレットを使用します。パスワードレス認証ではありません。 もし使うなら、保護されたアプリケーション設定からシークレットを読み取ってください。 SQL認証は、SQL認証をサポートするターゲットにのみ代替手段として使われます。FabricのSQLデータベースもウェアハウスもSQL認証をサポートしていません。

認証を環境に合わせて調整する

各接続に1つの認証機構を使いましょう。 Authenticationに切り替える際には、古いユーザー名やパスワード、AccessToken設定をそのままにしないようにしましょう。

Environment Configuration 責任
システム割り当て管理型アイデンティティを持つAzureホスト Authentication を ActiveDirectoryMsi に設定します。 ユーザー名やパスワードは提供しないでください。 ODBCはホストのアイデンティティエンドポイントからトークンを取得します。
ユーザー割り当てマネージド ID を持つ Azure ホスト Authentication を ActiveDirectoryMsi に設定します。 SQLSRVの UID オプションまたはPDOのユーザー名引数を通じて、ID の識別子を指定します。 パスワードは入力しないでください。 必要なIDはホスティングサービスによって異なります。 App ServiceやContainer InstancesはクライアントIDを使用します。他のホストについてはODBCのID に関するガイダンスを確認してください。
外部トークンプロバイダーを持つワークステーションまたはCI SQLサービスのトークンを取得し、AccessToken を設定します。 ユーザー名、パスワード、Authentication設定を省略してください。 アプリケーションやアイデンティティライブラリがトークンを取得し、更新します。 どちらのPHP拡張機能も自動的にAzure CLIのサインインを使いません。
クライアントシークレットを持つサービスプリンシパル Authentication を ActiveDirectoryServicePrincipal に設定します。 SQLSRVの場合は、 UID をクライアントIDに、 PWD をシークレットに設定します。 PDOの場合は、クライアントIDとシークレットをコンストラクタのユーザー名とパスワードの引数として渡します。 シークレットを保護し、ローテーションします。 この方法はパスワード不要ではありません。
それをサポートするターゲットでのSQLログイン SQLSRVは UID/PWDを使用します。PDOはコンストラクタ引数2と3を使用します。 ターゲットはSQLの認証情報を検証します。 このオプションはどちらのFabric製品にも当てはまりません。

Azureリソース管理のトークンではなく、SQLサービス用のトークンをリクエストしてください。 トークンの オーディエンス は、それを受け入れるサービスを特定します。 Azure パブリック クラウドの場合は、アイデンティティ ライブラリからスコープ https://database.windows.net/.default を要求してください。 別のクラウドに適したリソースを確認してください。 トークンを文字列としてPHP拡張に渡してください。手動でODBCのアクセストークン構造に変換しないでください。

ワーカーが実行を続けている間にトークンが期限切れになることがあります。 有効なトークンを取得してから別の接続を開き、長期間実行するワーカーでは必要に応じてトークンを更新してください。 アクセストークンを含むDSNは絶対にログに入ってはいけません。 ODBC認証の詳細については、「ODBCドライバーでのMicrosoft Entra IDの使用」をご覧ください。

暗号化と本人確認は別々に行ってください

Encrypt=true 暗号化されたトランスポートを要求します。 TrustServerCertificate=false サーバー証明書の検証(その識別情報を含む)が必要です。 Microsoft Entra認証は、あなたのアプリケーションが誰であるかを確立するものであり、サーバー証明書検証の代わりにはなりません。

SQLサービスが提供するエンドポイントを使用し、クライアントOSの証明書トラストストアを維持します。 ホスト名をIPアドレスに置き換えて名前解決の問題を回避しないでください。 プライベートエンドポイントの場合、サービスの期待される接続名を保持しつつ、名前の解決とルーティングを修正します。

LoginTimeout 接続確立を制限します。 QueryTimeout SQLSRVおよび PDO::SQLSRV_ATTR_QUERY_TIMEOUT PDO_SQLSRV は、文の実行に適用されます。 クエリタイムアウトを上げても、マネージド ID のエンドポイントの欠落や誤ったデータベースユーザーを修復することはできません。

故障段階ごとのトラブルシューティング

失敗段階 確認すべきこと
PHP では拡張モジュールを読み込めません ランタイムバージョン、アーキテクチャ、拡張ビルド、ODBC インストール、およびアプリケーションプロセスで使用される php.ini ドライバーを確認してください。
伝送制御プロトコル(TCP)接続がタイムアウトします コピーしたエンドポイントとポート、名前解決、ファイアウォール ルール、仮想ネットワーク ルーティング、およびプライベート エンドポイントの構成を PHP ホストから確認してください。
証明書の検証に失敗します エンドポイント名、証明書チェーン、クライアントのトラストストアを確認してください。 証明書検証を有効にしておきましょう。
マネージドIDはトークンを取得することはできません このホストでアイデンティティが有効であること、そしてアイデンティティエンドポイントが利用可能であることを確認しましょう。 普通のノートパソコンでActiveDirectoryMsiをテストして、Azure CLI のサインインでそれを満たせると期待しないでください。
トークン認証が失敗する トークンの意図されたサービス、有効期限、テナント、そしてアイデンティティを確認してください。 そのIDのデータベースアクセスを確認してください。 ユーザー名、パスワード、 Authentication 設定はすべて削除してください。
ログインは成功しますが、選択したデータベースは開けません データベース名と、その管理者が対象の ID を作成したか、またはその ID にアクセス権を付与したことを確認してください。
接続は開きますが、アプリケーションクエリが失敗します オブジェクトの権限と対象でサポートされる T-SQL 機能を確認してください。 接続テストはアプリケーション スキーマへのアクセスを確立しません。
データウェアハウスの接続設定の拒否 SQLSRVオプション配列またはPDO DSNでMultipleActiveResultSetsをfalseに設定し、Microsoft Entra認証を使います。

SQLSRVは false を返し、 sqlsrv_errors()を通じてエラーコレクションを公開します。 PDO の構築は PDOException をスローします; 例では、ステートメントの失敗に対する例外も有効にします。 制限ログに即座に診断情報を記録し、SQLSRVの警告とエラーを区別してください。 生の診断、トークン、接続情報はブラウザに返さないでください。

接続が途切れた場合の計画

サービスはアイドルセッションを切断したり、メンテナンスやフェイルオーバー中に操作を中断したりすることができます。 ODBCのアイドル接続の回復力やアプリケーションリトライは異なる問題を解決します。 再試行キーワードや制御切断テストについては、 アイドル接続レジリエンシーを参照してください。

クライアントが接続を失ったからといって書き込みをやり直すのはやめましょう。 サーバーは応答が失われる前にコミットしていた可能性があります。 アプリケーション固有の再試行ポリシーと重複作業検出の方法を使いましょう。 リリース文と接続は、リクエストやジョブの完了時を処理し、エラーパスも含みます。 ライフサイクルおよびプーリングの動作については、「サーバーへの接続」を参照してください。