Drivers da Microsoft para PHP para SQL Server

Descarregar o driver PHP

Os Microsoft Drivers for PHP for SQL Server são extensões PHP que permitem ler e escrever dados no Microsoft SQL Database Engine a partir de scripts PHP. O pacote inclui dois drivers que envolvem o mesmo Microsoft ODBC Driver for SQL Server e partilham as mesmas opções de ligação, por isso podes escolher a API que se adequa à tua base de código:

  • O SQLSRV expõe uma API procedural (sqlsrv_*funções) adaptada às funcionalidades do SQL Server.
  • PDO_SQLSRV implementa a interface PHP Data Objects (PDO), pelo que o código que já usa PDO para outras bases de dados pode direcionar SQL Server com alterações mínimas.

Ambos os drivers estabelecem ligação ao Base de Dados SQL do Azure, ao SQL Database no Microsoft Fabric, ao Azure SQL Managed Instance e a todas as versões e edições suportadas do SQL Server (incluindo as edições Express). Eles usam fluxos PHP para mover grandes valores binários e de caracteres sem os carregar totalmente na memória.

Escolhe o teu ponto de partida

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

Use este excerto como ponto de partida para uma ligação de SQL do Azure orientada para produção com o driver PDO_SQLSRV. Lê o servidor e a base de dados a partir de variáveis de ambiente (por exemplo, as definições da aplicação Serviço de Aplicações do Azure), autentica-se com uma identidade gerida, ativa a Segurança da Camada de Transporte (TLS) com validação de certificados de servidor, define um timeout de login que cobre um failover de arranque a frio, e define ConnectRetryCount e ConnectRetryInterval para a resiliência da ligação inativa do SQL Server. Os auxiliares connectWithRetry e queryWithRetry ao nível da aplicação encapsulam tanto o estabelecimento inicial da ligação como cada instrução com um backoff exponencial limitado, e separam os erros transitórios de ligação (que requerem uma nova ligação) dos erros transitórios de consulta (que reutilizam a mesma ligação).

Requer o PHP 8.0 e versões posteriores, a extensão PDO_SQLSRV e o controlador ODBC da Microsoft para SQL Server 17.3.1.1 e versões posteriores para Authentication=ActiveDirectoryMsi. Para a lista completa de valores suportadosAuthentication, consulte Connect using Microsoft Entra authentication.

<?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 fragmento de código está otimizado para grupos de failover do Base de Dados SQL do Azure e o Azure SQL Managed Instance.

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

  • ConnectRetryCount e ConnectRetryInterval são palavras-chave da cadeia de ligação ODBC que permitem a resiliência de ligações inativas do SQL Server: o controlador reconecta de forma transparente uma ligação inativa interrompida. Isto é diferente da queryWithRetry ao nível da aplicação, que repete uma instrução que falha com um erro transitório, como um deadlock ou a expiração do tempo limite da consulta. Os dois são complementares, por isso mantém ambos. Certifique-se de que LoginTimeout é, pelo menos, ConnectRetryCount * ConnectRetryInterval para que o trajeto de reconexão após inatividade disponha de todo o tempo previsto; o exemplo usa 90 segundos para cobrir 5 × 15 segundos de novas tentativas, mais alguma margem para o início de sessão inicial numa comutação pós-falha a frio.

  • Complemente as chamadas ao nível error_log() da aplicação com diagnósticos do lado do condutor. 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, consulte Atividade de registo.

    ; 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 gerida atribuída pelo utilizador, passe o ID da identidade como argumento $username do PDO (new PDO($dsn, $identityId, null, $options)). Use o ID de cliente da identidade no Serviço de Aplicações do Azure ou no Azure Container Instance; caso contrário, use o respetivo ID de objeto. Os drivers PHP herdam este comportamento do driver subjacente Microsoft ODBC para SQL Server; para mais informações, consulte Usar o Microsoft Entra ID com o driver ODBC. PDO_SQLSRV rejeita UID dentro da própria DSN, por isso usa o slot do construtor. Ao passar null como utilizador (como no exemplo), seleciona-se a identidade gerida atribuída pelo sistema ao anfitrião do Azure. Para SQLSRV (processual), passe UID no array de opções de ligação.

  • Define MultiSubnetFailover=true quando te ligas a um ouvinte de grupo de failover, ouvinte de grupo de disponibilidade ou endpoint de instância de cluster de failover. Defini-la melhora o desempenho da ligação tanto para ouvintes de grupos de disponibilidade de sub-rede única como de várias sub-redes. Para mais informações, consulte Suporte para Alta Disponibilidade, recuperação de desastres.

  • Para expansão de leitura ou uma secundária legível, adicione ApplicationIntent=ReadOnly ao nome da origem de dados (DSN).

  • Para clouds soberanas onde o certificado Subject Alternative Name (SAN) não inclui o host a que se está a ligar, adicione HostNameInCertificate ao DSN (por exemplo, *.database.usgovcloudapi.net para Azure Government).

  • O driver baseia-se no Microsoft ODBC Driver para SQL Server subjacente para aquisição de tokens. Identidade gerida, principal de serviço e fluxos de tokens de acesso passam todos pelo ODBC. Para obter mais informações, consulte Usando Microsoft Entra ID com o Driver ODBC.

  • Para maior segurança e portabilidade entre ambientes, mantenha a informação de ligação fora do seu código. Armazene a informação de ligação no sistema de configuração da sua aplicação e use o Azure Key Vault para valores sensíveis e definições de ligação geridas centralmente.

  • A ligação SQLSRV equivalente utiliza sqlsrv_connect($server, ['Database' => $database, 'Encrypt' => true, 'Authentication' => 'ActiveDirectoryMsi', /* ... */]) e devolve um recurso. O padrão de repetição é o mesmo: detetar um valor false devolvido por sqlsrv_connect, inspecionar sqlsrv_errors() para SQLSTATE e aguardar algum tempo antes de tentar novamente. Para um exemplo resolvido, veja o Passo 4: Ligue-se resilientemente a SQL com PHP.

  • As funções auxiliares de repetição leem $e->errorInfo[1] protegidas por isset(). PDOException::$errorInfo é declarado como ?array e tem como valor predefinido null, pelo que a verificação defensiva recorre a um código de controlador 0 e deixa que o prefixo SQLSTATE 08 determine se deve tentar novamente.

Para mais informações sobre cada parte desta configuração, veja:

Para o catálogo de erros transientes do SQL do Azure, veja Solucionar erros de ligação transitória.

Principais características

  • 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: Funciona em Windows, Linux e macOS com versões PHP suportadas.
  • Ligações encriptadas: Ligações encriptadas por TLS via Encrypt=true, com validação de certificados do servidor controlada por TrustServerCertificate.
  • Autenticação Microsoft Entra ID: Ligações sem palavra-passe com identidade gerida, principal de serviço e token de acesso fluem através do driver Microsoft ODBC subjacente para SQL Server.
  • Always Encrypted: Encriptação do lado do cliente para colunas sensíveis, com enclaves seguros opcionais para operações no local.
  • Resiliência da conexão: novas tentativas incorporadas para conexões inativas com ConnectRetryCount e ConnectRetryInterval.
  • Fluxos PHP: Leem e escrevem valores binários e de caracteres grandes como fluxos em vez de os carregar na memória.
  • Suporte abrangente para 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 de sistema Suporta versões para PHP, sistema operativo e SQL Server.
Matriz de suporte Matriz detalhada de compatibilidade para lançamentos de drivers PHP.
Descarregue os drivers Microsoft para PHP para SQL Server Links para download e divulgação de artefactos.
Tutorial de instalação para Linux e macOS Instala o driver e os seus pré-requisitos ODBC no Linux e macOS.
A carregar os controladores Ative as extensões em php.ini.
Começar com o driver PHP SQL Guia completo que reúne os quatro passos de introdução.
Visão geral do driver PHP SQL O que está no pacote e quando escolher SQLSRV ou PDO_SQLSRV.

Configurar e ligar

Artigo Description
Ligação ao servidor Abra uma ligação a uma instância do SQL Server a partir do PHP.
Opções de ligação Referência completa para palavras-chave de ligação, padrões e como os definir.
Connecting to Microsoft Base de Dados SQL do Azure Ligue uma aplicação PHP ao Base de Dados SQL do Azure.
Liga-te a uma porta especificada Especifique uma porta TCP não predefinida.
Pool de conexões Reutilizar ligações ODBC entre pedidos PHP.
Desativar Múltiplos Conjuntos de Resultados Ativos (MARS) Desliga o MARS para compatibilidade.
Suporte ao LocalDB Liga-te a uma instância do SQL Server LocalDB.
Suporte para Alta Disponibilidade, recuperação de desastres Escutas de grupos de disponibilidade e ativação pós-falha de várias sub-redes.
Resiliência da ligação ociosa Reconexão automática para conexões inativas interrompidas.

Authenticate

Artigo Description
Conectar usando a autenticação do Microsoft Entra Identidade gerida, principal de serviço, token de acesso e fluxos de palavra-passe.
Ligue-se usando autenticação SQL Server Use um login SQL com nome de utilizador e palavra-passe.
Ligue-se usando Windows authentication Utilize a autenticação integrada do Windows em hosts associados a um domínio.

Secure

Artigo Description
Considerações de segurança Modelo de ameaça e orientação aprofundada de defesa para aplicações PHP.
Sempre encriptado com os drivers PHP Configure a encriptação do lado do cliente para colunas sensíveis.
Sempre criptografado com enclaves seguros Permitir operações avançadas em colunas encriptadas com enclaves seguros.

Recuperar e atualizar dados

Artigo Description
Guia de programação Guia de programação abrangente para ambos os drivers.
Comparação das funções de execução Escolha a função de execução certa para a sua carga de trabalho.
Execução direta e preparada de instruções (PDO_SQLSRV) Quando usar execução direta versus declarações preparadas.
Recuperação de dados Obter linhas, colunas e valores em fluxo.
Atualização de dados Inserir, atualizar e apagar linhas.
Realizar consultas parametrizadas Vincule os parâmetros para se proteger contra injeções de SQL.
Enviar dados como fluxo Transmite valores binários e de caracteres grandes para o SQL Server.
Executar transações Agrupe instruções em transações atómicas.
Utilizar parâmetros com valores de tabela Passa um TABLE parâmetro para um procedimento armazenado.
Especifique um tipo de cursor e selecione linhas Escolha cursores apenas para avançar, estáticos, dinâmicos ou de conjunto de teclas.

Tipos de dados

Artigo Description
Conversão dos tipos de dados Como o driver mapeia os tipos PHP para os tipos SQL Server.
Tipos de dados padrão do SQL Server Tipo padrão de SQL Server para cada valor PHP.
Tipos de dados predefinidos do PHP Tipo PHP padrão para cada tipo de coluna do SQL Server.
Especificar tipos de dados do SQL Server (SQLSRV) Sobrepor o tipo SQL Server ao ligar parâmetros.
Especificar tipos de dados PHP Sobrepõe o tipo PHP ao buscar.
Enviar e recuperar dados UTF-8 Utilize PDO::SQLSRV_ENCODING_UTF8 para conversões Unicode de ida e volta.
Enviar e recuperar dados ASCII no Linux e macOS Processar conversões ASCII de ida e volta em anfitriões não Windows.
Formatar decimais e dinheiro (SQLSRV) Formate colunas do tipo decimal e money com o driver SQLSRV.
Formatar números decimais e valores monetários (PDO_SQLSRV) Formate colunas decimal e monetárias com o controlador PDO_SQLSRV.
Definições de localização fora do sistema Separadores decimais localizados e outras considerações locais.

Erros e diagnósticos

Artigo Description
Erros e avisos de manuseamento Gestão de erros e avisos em ambos os controladores.
Configurar o tratamento de erros e avisos (SQLSRV) Ajuste a forma como o driver SQLSRV reporta erros e avisos.
Lidar com erros e avisos (SQLSRV) Inspecione os erros retornados pelas funções SQLSRV.
Atividade de registo Ative o registo do controlador para recolha de dados de diagnóstico.

Implantar e operar

Artigo Description
Afinação de desempenho Gestão de ligações, processamento em lote, instruções preparadas, cursores, memória e monitorização do lado do servidor.
Troubleshooting Diagnosticar problemas comuns de instalação, ligação, consulta, tipo de dados, transação e contentores.

Conteúdo de referência

Artigo Description
Referência da API do driver SQLSRV Todos os sqlsrv_* funções, parâmetros e valores de retorno.
Referência do controlador 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 por versão com novas funcionalidades, correções de bugs, alterações de suporte à plataforma e links para download.
Sobre exemplos de código na documentação Convenções usadas pelos exemplos de código nesta secçã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 apoio Comunidade e canais de apoio.