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 リリースと、選択したPHP拡張機能および対応するODBC前提条件の両方をインストールしてください。 LocalDBのインストール時に、PHP拡張機能が読み込まれません。
- Windowsターミナルで
sqllocaldb.exe iを実行してインスタンスをリストアップしてください。 - もし
MSSQLLocalDBが存在しない場合、sqllocaldb.exe create MSSQLLocalDBを実行してください。 -
sqllocaldb.exe start MSSQLLocalDBを実行し、次にsqllocaldb.exe info MSSQLLocalDBを実行してインスタンスを確認します。 これらのステップはPHPプログラムを実行するWindowsアカウントで実行してください。 - プログラムの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オプションを追加しないでください。