Microsoft Drivers for PHP for SQL Server の概要

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

SQL ServerのPHP用Microsoftドライバには、SQLSRVとPDO_SQLSRVという2つのPHP拡張が含まれています。 PDO_SQLSRVはPHPデータオブジェクト(PDO)インターフェースを実装しています。 両方の拡張機能はMicrosoft ODBCドライバー for SQL Serverを使ってMicrosoft SQLに接続しています。 それぞれのPHP API、ドライバー固有のオプション、デフォルトのPHP型は異なります。 例えば、SQLSRVはデフォルトで日付と時刻の値を DateTime オブジェクトとして返しますが、PDO_SQLSRVはデフォルトで文字列を返します。 システム要件については、「PHP 用 Microsoft Drivers for SQL Server のシステム要件」を参照してください。

SQLSRVかPDO_SQLSRVを選びましょう

もしあなたが... Use
他にPDOコードがない新しいプロジェクトを始める場合 アプリケーションで一貫して使用するインターフェースを選びましょう。 SQLSRVは手続き関数と明示的なパラメータディスクリプタを公開します。 PDO_SQLSRV PDO オブジェクトや PDOStatement オブジェクトを中心に組織されたコードに適合します。
すでにPDOを別のデータベース(MySQL、PostgreSQL、SQLite)と組み合わせて使っています。 PDO_SQLSRV、そのため、データアクセス層がデータベース間で一貫性を保てます。
PDO接続オブジェクトを前提とするフレームワークやライブラリを使いましょう PDO_SQLSRV.
ストリームデータの送信タイミングをチャンク単位で手動でコントロールする必要があります sqlsrv_send_stream_data() を使用する SQLSRV。 PDO_SQLSRVまた、 PDO::PARAM_LOBとPHPストリームリソースをバインドすることで大きな値をストリーミングしますが、 execute() 中にストリーム全体を自動的に送信し、呼び出し元が制御するチャンク単位で送信しません。
すでにsqlsrv_*関数を呼び出しているアプリケーションを維持する SQLSRV(データアクセスコードをPDO用に書き直す予定でない限り)

拡張機能のどちらか、または両方をインストールしてください。 Windowsダウンロードには別々の拡張バイナリが含まれています。LinuxとmacOSでは、sqlsrvとpdo_sqlsrvパッケージを別々にインストールしてください。 両方を同じPHPプロセスで読み込むことができます。 SQLSRVは接続および文のリソースを返します。PDO_SQLSRVは PDO および PDOStatement オブジェクトを返します。 リソースを一方のAPIからもう一方のAPIに渡さないでください。

PDOを使っても、Transact-SQL(T-SQL)構文が他のデータベースに移植できるわけではありません。 PDOは共通のPHPインターフェースを提供します。クエリ、スキーマ、認証、ドライバー固有の属性は、引き続きMicrosoft SQLに依存する可能性があります。 同様に、手続き型拡張を使う場合でも、アプリケーション全体を手続き型で構成する必要はなく、自分のクラスからSQLSRVを呼び出すことができます。

両方のAPIで同じ結果を比較してください

アプリケーションが期待するPHP表現を選ぶ前に、これらのプログラムを実行してください。 それらは同じ整数、日付、SQL NULL 型を選択しますが、デフォルトは同一ではありません。 表やサンプルデータベースは必要ありません。

選択した拡張機能をインストールして読み込みます。 既存のSQL Serverテストデータベースに対して、SQL_SERVER、SQL_DATABASE、SQL_USER、SQL_PASSWORDをプロセス環境変数として設定します。 サーバー証明書は信頼でき、設定されたエンドポイントと一致しなければなりません。 セットアップや Azure を使わないパスワードレスの代替方法については、「サーバーへの接続」をご覧ください。

SQLSRV

この完全なプログラムを compare-sqlsrv.phpとして保存し、 php compare-sqlsrv.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]) . '}';
}
$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 {
    $stmt = sqlsrv_query($conn, "SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    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 (!is_array($row) || $row['CountValue'] !== 42
        || !($row['DayValue'] instanceof DateTime)
        || $row['DayValue']->format('Y-m-d') !== '2026-10-19'
        || $row['Missing'] !== null) {
        throw new RuntimeException('Unexpected SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

予想される出力:

int, DateTime, null

PDO_SQLSRV

この別のプログラムを compare-pdo.phpとして保存し、 php compare-pdo.php実行してください。 あえて数値や日付は、PDO_SQLSRVのデフォルトのままにします。

<?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::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
    ]
);
$stmt = null;
try {
    $stmt = $pdo->query("SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row !== ['CountValue' => '42', 'DayValue' => '2026-10-19', 'Missing' => null]) {
        throw new RuntimeException('Unexpected PDO_SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

予想される出力:

string, string, null

両プログラムとも明示的に名前付き結果キーを要求します。 これらのPHP配列は、ゼロベースの数値インデックスではなく、 CountValueのような列名を使用します。 SQL NULL はどちらのAPIでもPHP null になります。 空文字列や結果行が欠落しているものではありません。

両プログラムとも環境から実際のデータベース名、ユーザー名、パスワードを読み取ります。 PHPドライバーのODBCスタイルの接続処理のために、これらの値を一度エスケープします。 閉じ波かっこを二重にして値を波かっこで囲むことで特殊文字は保持されます。データベースの名前を変更したり、保存されたパスワードを変更したりしません。 詳細は「 サーバーへの接続」をご覧ください。

例はエラー時に止まり、finally内でリソースを解放します。 SQLSRVは false および sqlsrv_errors()を通じてデータベースの障害を報告します。PDO_SQLSRV は接続障害で例外をスローし、設定されたエラーモードではクエリ失敗に対して例外を使用します。 ウェブアプリケーションでは、リクエストを処理するコード内でこれらの例外をキャッチします。 診断の詳細はブラウザに戻すのではなく、保護ログに記録しましょう。

エクササイズが終わったら、もう必要ない compare-sqlsrv.php を削除して compare-pdo.php してください。 テストが終わったら、認証情報環境変数をテストプロセスから削除してください。

タイプ、エンコーディング、エラー処理の選択

アプリケーションがどのPHPタイプを期待するか、テキストやエラーの処理方法、データベースリソースのリリース時期を決めましょう。

意思決定 SQLSRV PDO_SQLSRV アプリケーションコードへの影響
整数結果のタイプ SQL の整数 列用のネイティブPHP整数。 デフォルトで文字列; PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE リクエストでは数値のPHP型がサポートされます。 厳密な比較やシリアル化出力は異なる場合があります。 すべてのSQLの数値型がPHPの整数やfloatに当てはまるとは限らない。
日付と時刻の結果 DateTime デフォルトでオブジェクトを選びます。 ReturnDatesAsStrings 文字列を選択します。 デフォルトで文字列; PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE オブジェクトを選択します。 シリアライズやアプリケーションコードに渡す前に、表現を正規化してください。
文字エンコード CharacterSet => 'UTF-8'明示的に設定します。 UTF-8がデフォルトです。 PDO::SQLSRV_ATTR_ENCODINGで設定してください。 SQLSRVオプションをPDO DSNに移行しないでください。
エラー処理 falseを確認し、すぐにSQLSRVのエラーコレクション全体をキャプチャしてください。 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTIONを構成します。 行が欠けている場合とクエリ失敗時には異なる処理が必要です。
パラメータ再利用 sqlsrv_prepare()記述子で変数を参照渡しでバインドします。 変数には bindParam() 、現在の値には bindValue() を使いましょう。 変数の再割り当ては参照バインディングに影響し、以前の値バインディングには影響しません。
Cleanup ステートメントを解放し、その後接続リソースを閉じます。 リリースステートメント参照を選び、その後PDOオブジェクトを操作します。 文は別の参照が nullに設定された後もPDO接続を存続させることができます。

既存のアプリケーションを移行する場合は、データベースコードを変更する前に代表的な値を用いてこれらの動作をテストしてください。 非ASCIIテキスト、SQL NULL、日付、正確な小数点値、保存手続きの出力パラメータを含めてください。 また、フレームワークがPDO属性をどのように設定しているかも比較してください。 関数名を置き換えるだけではエラー処理、参照バインディング、PHP型の返還は移行しません。

両方のAPIで書き読みのワークフローをうまく行うには、 プログラミングガイドを活用してください。 繰り返し実行および型付き入力の場合は、 クエリ実行関数の比較をご利用ください。

各コンポーネントが何をするのかを知っておく

拡張機能の選択によってPHP APIや型変換が変わります。 両方の拡張機能はODBCを使ってサーバーとの通信、接続の暗号化、認証を行います。 オペレーティングシステムは、Windows 認証やKerberosなどの信頼できる証明書やサービスを提供します。 SQLターゲットは権限、スキーマ、サポートされるT-SQL文を制御します。

比較プログラムはSQL ServerへのSQL認証を使用します。 Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics、FabricのSQL Database、またはWarehouse in Fabricでは、フェッチパターンを再利用する前にサービスエンドポイントと対応認証を設定してください。 両方のFabric製品にはMicrosoft Entra ID認証が必要です。ウェアハウスはまた、複数のアクティブ結果セット(MARS)を無効化する必要があります。 SQL Serverで型比較が成功しても、異なるターゲットがこの概要で挙げられたすべての機能をサポートするとは限りません。

両方の拡張機能が提供するもの

  • ターゲットでのサポート状況に応じて、統合認証、SQL 認証、Microsoft Entra ID 認証が対応可能です。 マネージドIDはアプリケーションのパスワードを使いません。 ActiveDirectoryServicePrincipal クライアントIDとクライアントシークレットを使用します。 詳細は「 サーバーへの接続」をご覧ください。
  • パラメータ化されたクエリ、プリペアドステートメント、および方向付き(入力/出力)パラメータ。 詳細については、「 実行関数の比較 」および「 方向パラメータの使用」を参照してください。
  • トランザクション、大きな文字やバイナリ値のストリーム入力パラメータ、テーブル値パラメータなどです。
  • 常に暗号化されており、ODBCドライバーやSQL Serverターゲットがサポートするセキュアエンクレーブも含まれます。 詳細については、「PHP 用 Microsoft Drivers for SQL Server で Always Encrypted を使用する」をご覧ください。
  • SQL Server、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics、Microsoft FabricのSQL Database、およびMicrosoft FabricのWarehouseへの接続。 認証やSQL機能は対象によって異なります。AzureおよびFabric接続を参照してください。