LocalDB のサポート

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

SQL Server Express LocalDBは、Windows専用の軽量なユーザーインスタンスモードであるSQL Server Expressです。 両方のドライバーは、 (localdb)\<instance-name> サーバー名フォームを使って、名前付きインスタンスに接続するのと同じ方法でLocalDBインスタンスに接続します。

解説

LocalDBはWindowsユーザーアカウントで動作します。 これらのプログラムはMicrosoft Entra認証ではなく、Windows統合認証を使用しています。 ユーザー単位のデータベースインスタンスがワークフローに合う場合は、ローカルWindows開発に使うのが良いでしょう。 コンテナイメージでもAzureサービスでもありません。

Note

LocalDBはLinuxやmacOSでは利用できません。 代わりにサポートされているホスト上のSQL Serverインスタンスに接続してください。 コンテナについては、サポートされているSQL Server on Linuxプラットフォームを確認してください。すべてのmacOSやLinuxアーキテクチャがSQL Serverコンテナイメージを動かせるとは限りません。

LocalDBインスタンスに接続

サポート対象の SQL Server Express LocalDB リリースをインストールし、ODBC の前提条件と、選択した PHP 拡張機能の両方をインストールしてください。 LocalDBのインストール時に、PHP拡張機能が読み込まれません。

  1. Windowsターミナルでsqllocaldb.exe iを実行してインスタンスをリストアップしてください。
  2. MSSQLLocalDB が存在しない場合は、sqllocaldb.exe create MSSQLLocalDB を実行します。
  3. sqllocaldb.exe start MSSQLLocalDBを実行し、次にsqllocaldb.exe info MSSQLLocalDBを実行してインスタンスを確認します。 これらのステップはPHPプログラムを実行するWindowsアカウントで実行してください。
  4. プログラムの1つを保存して、コマンドライン版PHPを使って実行してください。 それぞれがデフォルトで master に接続し、ターゲットが実際にLocalDBであることを検証します。 サンプルデータベースやSQLパスワードは不要です。

インスタンス名は Windows マシンと所有アカウントに対してローカルです。 それはDNSホスト名でも、TCPポートでも、他のコンピュータへの接続でもありません。

SQLSRV

このプログラムを connect-localdb-sqlsrv.phpとして保存し、php connect-localdb-sqlsrv.phpを実行してください。

<?php
$instance = getenv('LOCALDB_INSTANCE') ?: 'MSSQLLocalDB';
$database = getenv('LOCALDB_DATABASE');
if ($database === false || $database === '') {
    $database = 'master';
}
$file = getenv('LOCALDB_MDF');
$databaseValue = '{' . str_replace('}', '}}', $database) . '}';
$options = ['Database' => $databaseValue, 'LoginTimeout' => 30, 'CharacterSet' => 'UTF-8'];
if ($file !== false && $file !== '') {
    if ($database === 'master' || !is_file($file)) {
        throw new RuntimeException('Set a non-master database name and an accessible MDF path.');
    }
    $options['AttachDBFileName'] = '{' . str_replace('}', '}}', $file) . '}';
}
$conn = sqlsrv_connect('(localdb)\\' . $instance, $options);
if ($conn === false) {
    throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$stmt = null;
try {
    $stmt = sqlsrv_query(
        $conn,
        "SELECT DB_NAME() AS DatabaseName, CAST(SERVERPROPERTY('IsLocalDB') AS int) AS IsLocalDB"
    );
    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, 'IsLocalDB' => 1]) {
        throw new RuntimeException('Expected the selected LocalDB database.');
    }
    echo 'LocalDB database: ', $row['DatabaseName'], PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

PDO_SQLSRV

この別のプログラムを connect-localdb-pdo.phpとして保存し、 php connect-localdb-pdo.php実行してください。

<?php
$instance = getenv('LOCALDB_INSTANCE') ?: 'MSSQLLocalDB';
$database = getenv('LOCALDB_DATABASE');
if ($database === false || $database === '') {
    $database = 'master';
}
$file = getenv('LOCALDB_MDF');
$databaseValue = '{' . str_replace('}', '}}', $database) . '}';
$dsn = "sqlsrv:Server=(localdb)\\$instance;Database=$databaseValue;LoginTimeout=30";
if ($file !== false && $file !== '') {
    if ($database === 'master' || !is_file($file)) {
        throw new RuntimeException('Set a non-master database name and an accessible MDF path.');
    }
    $dsn .= ';AttachDBFileName={' . str_replace('}', '}}', $file) . '}';
}
$pdo = new PDO($dsn, null, null, [
    PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
    PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE => true,
    PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
]);
$stmt = null;
try {
    $stmt = $pdo->query(
        "SELECT DB_NAME() AS DatabaseName, CAST(SERVERPROPERTY('IsLocalDB') AS int) AS IsLocalDB"
    );
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row !== ['DatabaseName' => $database, 'IsLocalDB' => 1]) {
        throw new RuntimeException('Expected the selected LocalDB database.');
    }
    echo 'LocalDB database: ', $row['DatabaseName'], PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

デフォルト構成での期待出力:

LocalDB database: master

SQLSRVは接続リソースを返し、接続失敗を falseとして報告します。 PDO はオブジェクトを返し、インスタンス化に失敗した場合は PDOException をスローします。 PDO プログラムでは数値の取得が明示的に有効になっているため、intの値は PHP int となり、SQLSRV の結果と一致します。 どちらも文字データには UTF-8 を使用しており、クエリが失敗した場合でもステートメントと接続ハンドルを解放します。

既存のデータベースを選択するか、ファイルを添付します

プログラムは以下のオプションのプロセス変数を受け入れます:

Variable Meaning
LOCALDB_INSTANCE (localdb)\ というプレフィックスを除いたインスタンス名。 既定値は MSSQLLocalDB です。
LOCALDB_DATABASE 既存のデータベース名、またはアタッチするデータベースに付ける名前。 既定値は master です。
LOCALDB_MDF 添付する、既存のアクセス可能な .mdf ファイルへの絶対パス。 すでに登録済みのデータベースに接続する際は省略してください。

インスタンスに登録済みのデータベースを使用する場合は、 LOCALDB_DATABASE を設定し、 LOCALDB_MDF は未設定のままにします。 既存のデータベースファイルを添付するには、両方設定してください。 たとえば、PowerShell で以下を実行します。

$env:LOCALDB_DATABASE = 'myData'
$env:LOCALDB_MDF = 'C:\Data\myData.mdf'

この目的のために用意されたデータベース ファイルを使用してください。別の実行中のインスタンスにまだ紐づいているファイルは使用しないでください。 Windowsアカウントにデータベースファイルとそのディレクトリへのアクセス権を付与します。 AttachDBFileName は、欠落している MDF ファイルを作成したり、データベースを移行したり、互換性のないデータベース ファイルのバージョンを解決したりすることはありません。 アタッチすることで、データベースをインスタンスに登録します。PHP を終了しても、デタッチされたり削除されたりすることはありません。 それぞれの API の添付ファイルパスを、デタッチされた状態から個別にテストしてください。両方を個別に検証する必要がある場合は、この手順を行ってください。

PHP の単一引用符で囲まれた文字列では、サーバー文字列に含まれるバックスラッシュは \\ としてエスケープされます。 PHPの二重引用文字列もバックスラッシュや変数を解釈するため、PDOプログラムはインスタンス文字列を意図的に構成します。 両プログラムとも、接続用にデータベース名をエスケープしつつ、検証や結果確認のために元の名前は保持します。 また、添付ファイルの値をエスケープする前に、実際のファイル システムのパスも確認します。 各接続値について、閉じ中括弧を 2 つ重ねて、その値を中括弧で囲みます。 SQLSRV では、接続配列で指定される文字列オプションに対してもエスケープ処理を行う必要があります。 LOCALDB_DATABASEとLOCALDB_MDFを実際の名前と経路に合わせ、自分でブレースを追加したり二重にしたりせずに設定してください。

これらの接続はリモートサーバーではなくローカルインスタンスを使用します。 リモートSQL Server、Azure SQL Database、Azure SQL Managed Instance、Azure Synapse Analytics、FabricのSQL Database、またはWarehouse in Fabricの場合は、実際のサービスエンドポイントを使いましょう。 認証、暗号化、証明書の検証を明示的に設定してください。 詳細は「 サーバーへの接続」をご覧ください。

アカウントおよびインスタンスの問題を診断する

また、コマンドラインから sqlcmdを使ってLocalDBインスタンスのデータベースを管理することも可能です。例えば sqlcmd -S "(localdb)\MSSQLLocalDB"。 インタラクティブな Windows アカウントが所有する LocalDB インスタンスは、インターネット インフォメーション サービス (IIS) アプリケーションプールの ID に対して自動的にアクセス権を付与するわけではありません。 PHPを実行するアカウントを変更する際は、インスタンスの所有権とファイルの権限を確認してください。 詳細については、SQL Server Express LocalDBをご覧ください。

症状: チェック
sqllocaldb.exe が見つかりません LocalDBがインストールされていること、そしてそのユーティリティが端末で利用可能であることを確認しましょう。 PHPドライバーをインストールするだけでは不十分です。
そのインスタンスは見つかりません インスタンスを、PHP を実行しているのと同じ Windows アカウントとして登録し、LOCALDB_INSTANCE を確認してください。
最初の接続は時間がかかりすぎます インスタンスを明示的に起動し、ドキュメントに記載されたログインタイムアウトで再試行してください。 無期限に再試行するのではなく、インスタンスの起動失敗を調査してください。
master は動作するが、myData は動作しない そのインスタンスにデータベースが存在するか確認するか、アクセス可能なアタッチメント ファイルとデータベース名を設定してください。
ファイル添付エラー 正確なパス、ファイル所有権、ディレクトリ権限、ファイルがすでに使用中かどうか、LocalDBのバージョン互換性を確認してください。
ターミナルPHPは動作しますが、IISでは動作しません アカウント、インスタンス所有権、ファイルアクセス、ランタイム設定、拡張機能の読み込みを比較してください。 インタラクティブなテストでウェブホスティングへのアクセスが証明されるとは思わないでください。

LocalDB の起動およびユーザーごとの所有権は、SQL Server LocalDB と Windows に帰属します。 PHP拡張はODBCを通じて接続オプションを提供します。 インスタンス所有の問題を補うためにSQL認証情報やMicrosoft Entraオプションを追加しないでください。