Drivers da Microsoft para PHP para SQL Server

Baixar driver PHP

Os drivers Microsoft para PHP para SQL Server são extensões PHP que permitem ler e gravar dados no Microsoft SQL Mecanismo de Banco de Dados a partir de scripts PHP. O pacote vem com dois drivers que envolvem o mesmo driver Microsoft ODBC para SQL Server e compartilham as mesmas opções de conexão, então você pode escolher a API que se encaixa no seu código:

  • O SQLSRV expõe uma API procedural (sqlsrv_*funções) adaptada para recursos do SQL Server.
  • PDO_SQLSRV implementa a interface PHP Data Objects (PDO), então o código que já usa PDO para outros bancos de dados pode direcionar SQL Server com mudanças mínimas.

Ambos os drivers se conectam ao Banco de Dados SQL do Azure, ao banco de dados SQL no Microsoft Fabric, ao Instância Gerenciada de SQL do Azure e a todas as versões e edições com suporte do SQL Server (incluindo as edições Express). Eles usam fluxos PHP para mover grandes valores binários e de caracteres sem carregá-los totalmente na memória.

Escolha o ponto de partida

Linha de base de produção para SQL do Azure

Use esse trecho como ponto de partida para uma conexão SQL do Azure voltada para produção com o driver PDO_SQLSRV. Ele lê o servidor e o banco de dados a partir de variáveis de ambiente (configurações do aplicativo do Serviço de Aplicativo do Azure, por exemplo), autentica com uma identidade gerenciada, habilita a Segurança da Camada de Transporte (TLS) com validação de certificado do servidor, define um tempo limite de login que cobre uma falha de inicialização a frio e define ConnectRetryCount e ConnectRetryInterval para resiliência de conexão ociosa do SQL Server. Os auxiliares connectWithRetry e queryWithRetry em nível de aplicativo envolvem a conexão inicial e cada instrução com uma retirada exponencial limitada e separam erros de conexão transitórios (que exigem uma nova conexão) de erros de consulta transitórios (que reutilizam a mesma conexão).

Requer PHP 8.0 e versões posteriores, a extensão PDO_SQLSRV e o Driver ODBC da Microsoft para SQL Server 17.3.1.1 e versões posteriores para Authentication=ActiveDirectoryMsi. Para a lista completa de valores suportadosAuthentication, veja Conectar usando autenticação Microsoft Entra.

<?php
declare(strict_types=1);

// Transient errors that require a fresh connection to recover. SQLSTATE values
// starting with '08' cover ODBC connection-established and connection-broken
// states (for example, 08001, 08S01).
const CONNECT_RETRY_SQLSTATE_PREFIX = '08';

// SQL Server error codes that are transient regardless of when they surface:
// 1205 (deadlock victim), 1222 (lock request timeout), and the Azure SQL
// throttling, mid-query failover, and "database not currently available"
// codes that arrive with SQLSTATE HY000.
const TRANSIENT_SERVER_ERROR_CODES = [1205, 1222, 40501, 40613, 40197, 10928, 10929, 49918];

/**
 * Open a connection, retrying transient failures with exponential backoff.
 */
function connectWithRetry(string $dsn, array $options, int $maxAttempts = 3): PDO
{
    for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
        try {
            $pdo = new PDO($dsn, null, null, $options);
            error_log(sprintf('connected on attempt %d/%d', $attempt, $maxAttempts));
            return $pdo;
        } catch (PDOException $e) {
            $sqlstate = (string) $e->getCode();
            $driverCode = isset($e->errorInfo[1]) ? (int) $e->errorInfo[1] : 0;
            $isTransient = str_starts_with($sqlstate, CONNECT_RETRY_SQLSTATE_PREFIX)
                || in_array($driverCode, TRANSIENT_SERVER_ERROR_CODES, true);
            if (!$isTransient || $attempt === $maxAttempts) {
                error_log(sprintf('connect failed on attempt %d/%d: %s', $attempt, $maxAttempts, $e->getMessage()));
                throw $e;
            }
            $delay = 2 ** ($attempt - 1); // 1, 2, 4 seconds
            error_log(sprintf('connect attempt %d hit transient %s/%d; retrying in %d seconds', $attempt, $sqlstate, $driverCode, $delay));
            sleep($delay);
        }
    }
    throw new RuntimeException('connectWithRetry exhausted retries');
}

/**
 * Run a parameterized query, retrying transient statement failures on the same
 * connection. Deadlocks (1205) roll back the transaction before the driver sees
 * the error, so rerunning a single statement is safe. If the statement was part
 * of a multistatement transaction, wrap the whole transaction in your own retry
 * loop so earlier statements replay too.
 */
function queryWithRetry(PDO $pdo, string $sql, array $params = [], int $maxAttempts = 3): PDOStatement
{
    for ($attempt = 1; $attempt <= $maxAttempts; $attempt++) {
        try {
            $stmt = $pdo->prepare($sql);
            $stmt->execute($params);
            return $stmt;
        } catch (PDOException $e) {
            $driverCode = isset($e->errorInfo[1]) ? (int) $e->errorInfo[1] : 0;
            $isTransient = in_array($driverCode, TRANSIENT_SERVER_ERROR_CODES, true);
            if (!$isTransient || $attempt === $maxAttempts) {
                error_log(sprintf('query failed on attempt %d/%d: %s', $attempt, $maxAttempts, $e->getMessage()));
                throw $e;
            }
            $delay = 2 ** ($attempt - 1);
            error_log(sprintf('query attempt %d hit transient code %d; retrying in %d seconds', $attempt, $driverCode, $delay));
            sleep($delay);
        }
    }
    throw new RuntimeException('queryWithRetry exhausted retries');
}

// Load endpoint details from application configuration. In Azure App Service,
// these can come from app settings or Key Vault-backed settings.
$server = getenv('SQL_SERVER') ?: null;
$database = getenv('SQL_DATABASE') ?: null;

if ($server === null || $database === null) {
    throw new RuntimeException('Set SQL_SERVER and SQL_DATABASE in your application configuration.');
}

$dsn = sprintf(
    'sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=%s;Database=%s;'
    . 'Encrypt=true;TrustServerCertificate=false;'
    . 'LoginTimeout=90;Authentication=ActiveDirectoryMsi;'
    . 'ConnectRetryCount=5;ConnectRetryInterval=15;'
    . 'MultiSubnetFailover=true;',
    $server,
    $database
);

$options = [
    PDO::ATTR_ERRMODE               => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE    => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES      => false,
    PDO::SQLSRV_ATTR_QUERY_TIMEOUT  => 30,
];

$pdo = connectWithRetry($dsn, $options);
$stmt = queryWithRetry($pdo, 'SELECT TOP (?) name FROM sys.databases ORDER BY name', [5]);
foreach ($stmt as $row) {
    echo $row['name'], PHP_EOL;
}

Este trecho de código foi ajustado para grupos de failover do Banco de Dados SQL do Azure e para o Instância Gerenciada de SQL do Azure.

  • Driver={ODBC Driver 18 for SQL Server} fixa o driver ODBC 18. Se o host também tiver ODBC 17 instalado, PDO_SQLSRV pode vincular ao ODBC 17. Versões antigas 17.x rejeitam valores mais Authentication recentes; por exemplo, Authentication=ActiveDirectoryMsi requerem ODBC 17.3.1.1 ou uma versão posterior. Veja Valor inválido especificado para o atributo de cadeia de conexão 'Authentication'.

  • ConnectRetryCounte ConnectRetryInterval são palavras-chave ODBC cadeia de conexão que possibilitam a resiliência da conexão ociosa no SQL Server: o driver reconecta de forma transparente uma conexão ociosa quebrada. Isso é diferente do queryWithRetry, em nível de aplicativo, que tenta novamente uma instrução que falha com um erro transitório, como um deadlock ou tempo limite de consulta. Os dois são complementares, então mantenha os dois. Certifique-se de que LoginTimeout seja pelo menos ConnectRetryCount * ConnectRetryInterval para que o caminho de reconexão ociosa receba seu orçamento total; O exemplo usa 90 segundos para cobrir 5 × 15 segundos de novas tentativas, além de uma margem para o login inicial em um failover a frio.

  • Complemente as chamadas error_log() no nível do aplicativo com diagnósticos do lado do driver. Para PDO_SQLSRV, defina pdo_sqlsrv.log_severity em php.ini (configurável apenas durante a inicialização); para SQLSRV, chame sqlsrv_configure("LogSubsystems", ...) em tempo de execução. Para mais informações, veja Atividade de registro.

    ; php.ini - enable PDO_SQLSRV driver diagnostics alongside the application-level
    ; error_log() calls in the sample. Use 1 (errors) in production; -1 (all) is
    ; useful during triage but very chatty.
    [pdo_sqlsrv]
    pdo_sqlsrv.log_severity = 1
    
  • Para uma identidade gerenciada atribuída pelo usuário, passe o ID da identidade como argumento $username do PDO (new PDO($dsn, $identityId, null, $options)). Use o ID do cliente da identidade no Serviço de Aplicativo do Azure ou Instância de Contêiner do Azure; caso contrário, use seu ID do objeto. Os drivers PHP herdam esse comportamento do driver Microsoft ODBC para SQL Server; para mais informações, veja Usando o Microsoft Entra ID com o driver ODBC. PDO_SQLSRV rejeita UID dentro do próprio DSN, portanto, use o slot do construtor. Passar null como o usuário (como o exemplo faz) seleciona a identidade gerenciada atribuída pelo sistema do host do Azure. Para SQLSRV (procedural), passe UID no array de opções de conexão.

  • Defina MultiSubnetFailover=true ao se conectar a um listener de grupo de failover, listener de grupo de disponibilidade ou ponto de extremidade de instância de cluster de failover. Definir isso melhora o desempenho da conexão para listeners de grupo de disponibilidade de sub-rede única e de várias sub-redes. Para mais informações, veja Suporte para Alta Disponibilidade, recuperação de desastres.

  • Para expansão de leitura ou réplica secundária para leitura, adicione ApplicationIntent=ReadOnly ao Nome da Fonte de Dados (DSN).

  • Para nuvens soberanas onde o certificado Subject Alternative Name (SAN) não inclui o host ao qual você está se conectando, adicione HostNameInCertificate ao DSN (por exemplo, *.database.usgovcloudapi.net para Azure Governamental).

  • O driver se baseia no Microsoft ODBC Driver for SQL Server subjacente para a obtenção de tokens. Os fluxos de identidade gerenciada, principal de serviço e token de acesso passam pelo ODBC. Para obter mais informações, consulte Usar o Microsoft Entra ID com o driver ODBC.

  • Para maior segurança e portabilidade entre ambientes, mantenha as informações de conexão fora do seu código. Armazene informações de conexão no sistema de configuração do seu aplicativo e use o Azure Key Vault para valores sensíveis e configurações de conexão gerenciadas centralmente.

  • A conexão SQLSRV equivalente usa sqlsrv_connect($server, ['Database' => $database, 'Encrypt' => true, 'Authentication' => 'ActiveDirectoryMsi', /* ... */]) e retorna um recurso. O padrão de repetição é o mesmo: capturar um retorno false de sqlsrv_connect, inspecionar sqlsrv_errors() em busca de SQLSTATE e aguardar antes de tentar novamente. Para um exemplo resolvido, veja Passo 4: Conecte-se resilientemente ao SQL com PHP.

  • Os auxiliares de repetição leem $e->errorInfo[1] protegido por isset(). PDOException::$errorInfo é declarado como ?array e tem como padrão null, portanto a verificação defensiva recorre a um código do driver 0 e deixa que o prefixo SQLSTATE 08 determine se deve tentar novamente.

Para obter mais informações sobre cada parte dessa configuração, consulte:

Para o catálogo de erros transitórios do SQL do Azure, consulte Solucionar problemas de erros de conexão transitórios.

Características principais

  • Duas APIs, um pacote de drivers: SQLSRV procedural para código SQL Server-first, ou PDO_SQLSRV para código PDO portátil.
  • Suporte a plataforma ampla: Roda em Windows, Linux e macOS com versões PHP suportadas.
  • Conexões criptografadas: Conexões criptografadas por TLS via Encrypt=true, com validação de certificado do servidor controlada por TrustServerCertificate.
  • Autenticação do Microsoft Entra ID: conexões sem senha com fluxos de identidade gerenciada, principal de serviço e token de acesso por meio do driver ODBC da Microsoft para SQL Server subjacente.
  • Always Encrypted: criptografia do lado do cliente para colunas sensíveis, com enclaves seguros opcionais para operações no local.
  • Resiliência de conexão: repetições de conexão ociosa integradas com ConnectRetryCount e ConnectRetryInterval.
  • Fluxos PHP: leia e grave grandes valores binários e de caracteres como fluxos em vez de carregá-los na memória.
  • Amplo suporte a tipos de dados do SQL Server: datetimeoffset, parâmetros com valor de tabela, nvarchar, e Unicode com PDO::SQLSRV_ENCODING_UTF8.

Introdução

Artigo Description
Requisitos do sistema Suportava versões para PHP, sistema operacional e SQL Server.
Matriz de suporte Matriz detalhada de compatibilidade para lançamentos de drivers PHP.
Baixe os drivers da Microsoft para PHP para SQL Server Links de download e artefatos de lançamento.
Tutorial de instalação para Linux e macOS Instale o driver e seus pré-requisitos ODBC no Linux e macOS.
Carregando os drivers Ative as extensões em php.ini.
Começando com o driver PHP SQL Passo a passo completo que integra as quatro etapas iniciais.
Visão geral do driver PHP SQL O que está no pacote e quando escolher SQLSRV ou PDO_SQLSRV.

Configuração e conexão

Artigo Description
Conectando ao servidor Abra uma conexão para uma instância do SQL Server a partir do PHP.
Opções de conexão Referência completa para palavras-chave de conexão, padrões e como configurá-las.
Conectar-se ao Banco de Dados SQL do Microsoft Azure Conecte uma aplicação PHP ao Banco de Dados SQL do Azure.
Conecte-se em uma porta especificada Aponte uma porta TCP não padrão.
Agrupamento de conexões Reutilize conexões ODBC entre requisições PHP.
Desabilite Múltiplos Conjuntos de Resultados Ativos (MARS) Desative o MARS para compatibilidade.
Suporte ao LocalDB Conecte-se a uma instância do LocalDB do SQL Server.
Suporte para Alta Disponibilidade, recuperação de desastres Ouvintes de grupo de disponibilidade e failover de várias sub-redes.
Resiliência da conexão ociosa Reconexão automática para conexões ociosas quebradas.

Authenticate

Artigo Description
Conectar-se usando a autenticação do Microsoft Entra Fluxos de identidade gerenciada, entidade de serviço, token de acesso e senha.
Conecte-se usando autenticação SQL Server Use um login SQL com nome de usuário e senha.
Conecte-se usando autenticação do Windows Usar a autenticação integrada do Windows em hosts ingressados no domínio.

Secure

Artigo Description
Considerações de segurança Modelo de ameaça e orientação aprofundada de defesa para aplicações PHP.
Always Encrypted com os drivers PHP Configure a criptografia do lado do cliente para colunas confidenciais.
Always Encrypted com enclaves seguros Habilite operações avançadas em colunas criptografadas com enclaves seguros.

Recuperar e atualizar dados

Artigo Description
Guia de programação Guia completo de programação para ambos os drivers.
Comparando funções de execução Escolha a função de execução certa para sua carga de trabalho.
Execução direta e preparada de instruções (PDO_SQLSRV) Quando usar execução direta versus instruções preparadas.
Recuperação de dados Busque linhas, colunas e valores de streaming.
Atualização dos dados Inserir, atualizar e excluir linhas.
Realizar consultas parametrizadas Vincule parâmetros para proteger contra injeção SQL.
Enviar dados como um fluxo Transmita valores binários e de caracteres grandes para o SQL Server.
Realizar transações Agrupar instruções em transações atômicas.
Uso de parâmetros com valores de tabela Passe um TABLE parâmetro para um procedimento armazenado.
Especifique um tipo de cursor e selecione linhas Escolher cursores somente para frente, estáticos, dinâmicos ou de conjunto de chaves.

Tipos de dados

Artigo Description
Conversão de tipos de dados Como o driver mapeia tipos PHP para tipos SQL Server.
Tipos de dados padrão do SQL Server Tipo padrão de SQL Server para cada valor PHP.
Tipos de dados padrão PHP Tipo padrão de PHP para cada tipo de coluna do SQL Server.
Especificar tipos de dados do SQL Server (SQLSRV) Substituir o tipo do SQL Server ao vincular parâmetros.
Especificar tipos de dados PHP Substituir o tipo do PHP ao buscar dados.
Enviar e recuperar dados UTF-8 Usar PDO::SQLSRV_ENCODING_UTF8 para viagens de ida e volta Unicode.
Enviar e recuperar dados ASCII no Linux e macOS Lidar com viagens de ida e volta ASCII em hosts não Windows.
Formatar decimais e dinheiro (SQLSRV) Formate as colunas decimais e de dinheiro com o driver SQLSRV.
Formatar decimais e valores monetários (PDO_SQLSRV) Formate colunas decimais e monetárias com o driver PDO_SQLSRV.
Configurações de localização fora do sistema Separadores decimais localizados e outras considerações locais.

Erros e diagnóstico

Artigo Description
Tratamento de erros e avisos Tratamento de erros e avisos com ambos os drivers.
Configurar o tratamento de erros e avisos (SQLSRV) Ajuste como o driver SQLSRV reporta erros e avisos.
Gerenciar erros e avisos (SQLSRV) Inspecione os erros retornados pelas funções SQLSRV.
Atividade de registro Habilitar o registro de logs do driver para captura de diagnóstico.

Implantar e operar

Artigo Description
Otimização do desempenho Gerenciamento de conexões, processamento em lote, instruções preparadas, cursores, memória e monitoramento no lado do servidor.
Solução de problemas Diagnosticar problemas comuns de instalação, conexão, consulta, tipo de dado, transação e container.

Conteúdo de referência

Artigo Description
Referência à API do driver SQLSRV Todas sqlsrv_* as funções, parâmetros e valores de retorno.
Referência do driver PDO_SQLSRV Métodos PDO e PDOStatement suportados pelo driver PDO_SQLSRV.
Constantes Constantes expostas pelos drivers, incluindo constantes de tipo e codificação.
Artigo Description
Notas de lançamento Histórico de versões por versão com novos recursos, correções de bugs, mudanças no suporte à plataforma e links para download.
Sobre exemplos de código na documentação Convenções usadas pelos exemplos de código nesta seção.
Exemplos de código para o driver SQL PHP Exemplos de aplicações de ponta a ponta para SQLSRV e PDO_SQLSRV.
Recursos de suporte Comunidade e canais de apoio.