LocalDB 的支援

下載 PHP 驅動程式

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 擴充功能。

  1. 在 Windows 終端機執行 sqllocaldb.exe i,列出你的執行個體。
  2. 如果MSSQLLocalDB不存在,請執行sqllocaldb.exe create MSSQLLocalDB。
  3. 執行 sqllocaldb.exe start MSSQLLocalDB,然後執行 sqllocaldb.exe info MSSQLLocalDB 以檢查該實例。 請以執行 PHP 程式的 Windows 帳號執行這些步驟。
  4. 儲存並用命令列 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 選項。