Suporte ao LocalDB

Baixar driver do PHP

SQL Server Express LocalDB é um modo leve de instância de usuário do SQL Server Express, disponível apenas para Windows. Ambos os drivers se conectam a uma instância LocalDB da mesma forma que se conectam a qualquer instância nomeada, usando o formato de nome do servidor (localdb)\<instance-name>.

Comentários

O LocalDB roda sob uma conta de usuário do Windows. Os programas usam autenticação integrada ao Windows, não a autenticação Microsoft Entra. Use-o para desenvolvimento local no Windows quando uma instância de banco de dados por usuário se encaixar no seu fluxo de trabalho. Não é uma imagem de container nem um serviço do Azure.

Note

O LocalDB não está disponível no Linux ou macOS. Conecte-se a uma instância do SQL Server em um host suportado, em vez disso. Para containers, verifique as plataformas Linux compatíveis com SQL Server; não presuma que toda arquitetura macOS ou Linux pode rodar a imagem do container do SQL Server.

Conecte-se a uma instância de LocalDB

Instale uma versão suportada do SQL Server Express LocalDB e também o pré-requisito ODBC e a extensão PHP que você selecionar. A instalação do LocalDB não carrega uma extensão PHP.

  1. Execute sqllocaldb.exe i no terminal do Windows para listar suas instâncias.
  2. Se MSSQLLocalDB não existir, execute sqllocaldb.exe create MSSQLLocalDB.
  3. Execute sqllocaldb.exe start MSSQLLocalDB, depois sqllocaldb.exe info MSSQLLocalDB para inspecionar a instância. Execute esses passos como a conta do Windows que executa o programa PHP.
  4. Salve e execute um dos programas com PHP de linha de comando. Cada um se conecta a master por padrão e verifica se o destino é realmente o LocalDB. Não é necessário um banco de dados de exemplo ou senha SQL.

O nome da instância é local para a máquina Windows e para a conta proprietária. Não é um nome de host DNS, porta TCP ou conexão com outro computador.

SQLSRV

Salve este programa como connect-localdb-sqlsrv.php, e execute 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

Salve esse programa separado como connect-localdb-pdo.php, e execute 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;
}

Saída esperada com a configuração padrão:

LocalDB database: master

SQLSRV retorna um recurso de conexão e reporta falhas de conexão como false. O PDO retorna um objeto e lança PDOException se a instanciação falhar. O programa PDO habilita explicitamente a busca numérica; então, o valor int é PHP int, que corresponde ao resultado SQLSRV. Ambos usam UTF-8 para dados de caracteres e instruções de versão, e identificadores de conexão mesmo quando uma consulta falha.

Selecione um banco de dados existente ou anexe um arquivo

Os programas aceitam estas variáveis opcionais de processo:

Variable Meaning
LOCALDB_INSTANCE Nome da instância sem o (localdb)\ prefixo. Usa MSSQLLocalDB como padrão.
LOCALDB_DATABASE Um nome de banco de dados existente, ou o nome a ser fornecido a um banco de dados anexado. Usa master como padrão.
LOCALDB_MDF Caminho absoluto para um arquivo existente e acessível .mdf para anexar. Omita isso ao conectar a um banco de dados já registrado.

Para usar um banco de dados já registrado na instância, defina LOCALDB_DATABASE e deixe LOCALDB_MDF não definido. Para anexar um arquivo de banco de dados existente, defina ambos. Por exemplo, no PowerShell:

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

Use um arquivo de banco de dados preparado para esse propósito, não um arquivo ainda vinculado a outra instância em execução. Conceda à conta do Windows acesso aos arquivos do banco de dados e ao diretório deles. AttachDBFileName não cria um arquivo MDF ausente, migra um banco de dados ou resolve uma incompatibilidade de versão do arquivo de banco de dados. Uma anexação registra o banco de dados com a instância; fechar o PHP não o desanexa nem exclui o item. Teste o caminho de anexação de cada API a partir de um estado desanexado se precisar verificar ambos de forma independente.

A barra inversa da string do servidor é escapada nas cadeias de aspas simples do PHP como \\. Cadeias de caracteres PHP com aspas duplas também interpretam barras invertidas e variáveis; então, o programa PDO cria intencionalmente a cadeia de caracteres de instância. Ambos os programas escapam do nome do banco de dados para a conexão, mantendo o nome original para validação e verificação de resultados. Eles também verificam o caminho real do sistema de arquivos antes de escapar do valor do anexo. Para cada valor de conexão, eles dobram as chaves de fechamento e colocam o valor entre chaves. O SQLSRV exige escape mesmo para opções de cadeia de caracteres fornecidas em sua matriz de conexão. Defina LOCALDB_DATABASE e LOCALDB_MDF para o nome e o caminho reais, sem adicionar ou dobrar as chaves você mesmo.

Essas conexões usam uma instância local, não um servidor remoto. Para SQL Server remoto, Banco de Dados SQL do Azure, Instância Gerenciada de SQL do Azure, Azure Synapse Analytics, banco de dados SQL no Fabric ou Warehouse no Fabric, use o endpoint real do serviço. Defina explicitamente autenticação, criptografia e validação de certificados. Para mais informações, veja Conectando ao servidor.

Diagnosticar problemas de conta e instância

Você também pode gerenciar os bancos de dados de uma instância de LocalDB pela linha de comando com sqlcmd, sqlcmd -S "(localdb)\MSSQLLocalDB"por exemplo. Uma instância do LocalDB que sua conta interativa do Windows possui não concede automaticamente acesso à identidade do pool de aplicações do Serviços de Informações da Internet (IIS). Verifique a propriedade da instância e as permissões do arquivo ao mudar a conta que roda PHP. Para mais informações, veja SQL Server Express LocalDB.

Sintoma Verificação
sqllocaldb.exe não foi encontrado Confirme que o LocalDB está instalado e que seu utilitário está disponível para o terminal. Instalar os drivers PHP não é suficiente.
A instância não foi encontrada Relacione as instâncias usando a mesma conta do Windows que executa o PHP e verifique LOCALDB_INSTANCE.
A conexão inicial demora demais Inicie a instância explicitamente e tente novamente com o tempo de login documentado. Investigue uma falha de inicialização da instância em vez de tentar indefinidamente.
master Funciona, mas myData não Confirme que o banco de dados existe nessa instância, ou configure um arquivo de anexação acessível e um nome de banco de dados.
Falha ao anexar arquivo Verifique o caminho exato, a propriedade do arquivo, permissões do diretório, se o arquivo já está em uso e a compatibilidade com versões do LocalDB.
Terminal PHP funciona, mas o IIS não Compare a conta, a propriedade da instância, o acesso a arquivos, a configuração de runtime e o carregamento de extensões. Não suponha que um teste interativo comprova o acesso à hospedagem na Web.

A inicialização do LocalDB e a posse por usuário pertencem ao SQL Server LocalDB e ao Windows. As extensões PHP fornecem opções de conexão via ODBC. Não adicione credenciais SQL ou opções do Microsoft Entra para compensar um problema de propriedade de instância.