SQL Server Express LocalDB 是 SQL Server Express 的一種輕量級使用者實例模式,僅支援 Windows 平台。 兩個驅動程式都會使用 (localdb)\<instance-name> 伺服器名稱格式,以與連線到任何具名執行個體相同的方式連線到 LocalDB 執行個體。
備註
LocalDB 是在 Windows 使用者帳號下執行的。 這些程式使用 Windows 整合的認證,而非 Microsoft Entra 認證。 當每個使用者的資料庫實例符合你的工作流程時,可以用它來在本機上進行 Windows 開發。 它不是容器映像檔或 Azure 服務。
Note
LocalDB 在 Linux 和 macOS 上都無法使用。 改為連接到受支援的主機上的 SQL Server 實例。 容器方面,請檢查支援的 Linux 上的 SQL Server 平台;不要假設每個 macOS 或 Linux 架構都能執行 SQL Server 容器映像。
連接到一個 LocalDB 執行個體
安裝支援的 SQL Server Express LocalDB 版本,以及你選擇的 ODBC 前置條件和 PHP 擴充功能。 LocalDB 安裝時未載入 PHP 擴充功能。
- 在 Windows 終端機執行
sqllocaldb.exe i,列出你的執行個體。 - 如果
MSSQLLocalDB不存在,請執行sqllocaldb.exe create MSSQLLocalDB。 - 執行
sqllocaldb.exe start MSSQLLocalDB,然後執行sqllocaldb.exe info MSSQLLocalDB以檢查該實例。 請以執行 PHP 程式的 Windows 帳號執行這些步驟。 - 儲存並用命令列 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 來處理字元資料,並且即使在查詢失敗時也會釋放 statement 和 connection handles。
選擇現有資料庫或附加檔案
程式接受以下可選的程序變數:
| 變數 | 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 程式會刻意構造連線字串。 兩個程式都會逃逸連接的資料庫名稱,但保留原始名稱以便驗證和結果檢查。 他們也會在跳脫附件值前檢查實際的檔案系統路徑。 對每個連接值,它們會重複閉括括號,並將值包圍在大括號中。 SQLSRV 要求即使對其連線陣列中提供的字串選項也必須跳脫。 設定 LOCALDB_DATABASE 和 LOCALDB_MDF 到實際名稱和路徑,不用自己加或加倍支架。
這些連線使用本地實例,而非遠端伺服器。 對於遠端 SQL Server、Azure SQL Database、Azure SQL 受控執行個體、Azure Synapse Analytics、Fabric 中的 SQL 資料庫,或 Fabric 中的 Warehouse,請使用實際的服務端點。 明確設定身分驗證、加密與憑證驗證。 更多資訊請參見 「連接伺服器」。
診斷帳號與實例問題
你也可以用 sqlcmd 從命令列管理 LocalDB 實例的資料庫,例如 sqlcmd -S "(localdb)\MSSQLLocalDB"。 你互動式 Windows 帳號擁有的 LocalDB 實例,並不會自動授予 Internet Information Services(IIS)應用程式池的存取權。 更換執行 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 選項。