Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Diagnostice e resolva problemas comuns quando utiliza os Microsoft Drivers for PHP for SQL Server para se ligar ao SQL Server, Base de Dados SQL do Azure, Azure SQL Managed Instance e base de dados SQL em Microsoft Fabric.
Para padrões gerais de tratamento de erros e avisos, veja Gestão de erros e avisos. Para a captura de diagnósticos do lado do controlador, veja Atividade de registo.
Problemas de instalação
Extensão não carregada
Sintomas:
-
phpinfo()não apresenta uma secçãosqlsrvoupdo_sqlsrv. -
PDOException: could not find driverao construir aPDOcom asqlsrv:DSN. -
Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().
Possíveis causas e soluções:
-
Extensão não ativada em php.ini. Verifica que tanto
extension=sqlsrvcomoextension=pdo_sqlsrvestão descomentados. No Windows, use o nome completo do ficheiro (extension=php_sqlsrv_84_ts_x64.dll). Para mais detalhes, veja Carregar os drivers. -
Configuração errada de segurança de rosca. O binário do driver deve corresponder à segurança de threads da sua build PHP (
tspara thread-safe,ntspara não-thread-safe). Executaphp -i | grep "Thread Safety"para verificar. Descarregue o binário correspondente na página de download. -
Controlador ODBC da Microsoft em falta. Os drivers PHP envolvem o Microsoft ODBC Driver for SQL Server. No Linux e macOS, instale
msodbcsql18(oumsodbcsql17) com o seu gestor de pacotes antes de carregar as extensões. No Windows, instala o driver ODBC a partir da página de download.
Verifique uma instalação bem-sucedida:
php -m | grep -i sqlsrv
Deves ver ambos pdo_sqlsrv e sqlsrv na saída.
Falha a instalação do PECL no Linux ou macOS
Sintomas:
error: ‘SQL_HANDLE_DBC’ undeclared (first use in this function)
fatal error: 'sql.h' file not found
Correção:
Instale os cabeçalhos de desenvolvimento ODBC antes de executar pecl install:
-
Ubuntu e Debian:
sudo apt-get install unixodbc-dev -
Red Hat, Fedora e CentOS:
sudo dnf install unixODBC-devel -
Alpine:
apk add unixodbc-dev -
macOS:
brew install unixodbc
Depois tenta:
sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv
Se pecl ainda assim falhar depois de instalar os cabeçalhos, a cadeia de ferramentas de construção pode estar incompleta. Instale phpize, re2c, e um compilador C++ (build-essential no Debian e Ubuntu, gcc-c++ make no Red Hat e Fedora, build-base no Alpine).
Para o caminho completo de instalação, veja o tutorial de instalação para Linux e macOS.
Múltiplas versões PHP instaladas
Sintomas:
phpinfo() no seu servidor web mostra uma versão do PHP, mas php -v na linha de comandos aparece outra, e o driver aparece carregado apenas numa delas.
Correção:
Cada versão do PHP tem o seu diretório php.ini e ext. Localiza o ficheiro de configuração correto com php --ini no ambiente em que falta o controlador e adiciona aí as linhas extension=. Reinicie o servidor web (Apache, Nginx + PHP-FPM ou IIS) após qualquer alteração php.ini.
Problemas de ligação
Impossível ligar-se ao servidor
Sintomas:
SQLSTATE[08001]: [Microsoft][ODBC Driver 18 for SQL Server]TCP Provider: A connection attempt failed
SQLSTATE[HYT00]: [Microsoft][ODBC Driver 18 for SQL Server]Login timeout expired
Possíveis causas e soluções:
O servidor não está acessível. Verifica se o nome do servidor e a porta estão corretos. A partir do host PHP, testar a conectividade TCP bruta.
# Linux and macOS nc -vz <server>.database.windows.net 1433 # Windows PowerShell Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433A firewall bloqueia o tráfego de saída na porta 1433. Firewalls corporativos e NSGs cloud frequentemente bloqueiam a porta de saída 1433. Adicione uma exceção, ou permita os intervalos de IP do Base de Dados SQL do Azure para a sua região.
SQL do Azure server firewall. Adicione o IP público do seu cliente às regras do firewall ao nível do servidor no portal Azure.
Instância nomeada. Para uma instância nomeada, verifique se o serviço SQL Server Browser está a correr no servidor e se o UDP 1434 está aberto. Ou ligue-se através da porta em vez de através do nome da instância.
Início de sessão falhado
Sintomas:
SQLSTATE[28000]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<user_id>'.
Possíveis causas e soluções:
- Modo de autenticação SQL desativado. As instâncias locais do SQL Server têm, por predefinição, apenas Autenticação do Windows. Ative a autenticação em modo misto no SQL Server Management Studio em propriedades>do servidor Segurança e depois reinicie o serviço SQL Server.
-
SQL do Azure credentials format. O SQL do Azure requer o nome de utilizador totalmente qualificado (
user@servername) ao ligar a ferramentas que não o adicionam automaticamente. - Utilizador não mapeado para a base de dados. Verifique se o login tem um mapeamento de utilizador na base de dados de destino e se o utilizador tem as permissões necessárias.
-
Prefira o Microsoft Entra ID. Para SQL do Azure, Azure SQL Managed Instance e base de dados SQL no Fabric, utilize autenticação Microsoft Entra (
Authentication=ActiveDirectoryMsi,Authentication=ActiveDirectoryServicePrincipal, ou um token de acesso) em vez de logins SQL. Veja Ligar usando a autenticação do Microsoft Entra.
Valor inválido especificado para o atributo de cadeia de ligação 'Authentication'
Sintomas:
SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Invalid value specified for connection string attribute 'Authentication'
Motivo:
O controlador ODBC comunica o erro, mas o verdadeiro problema é a que controlador o PDO_SQLSRV estava associado. Se a DSN não incluir a palavra-chave Driver= e o host tiver o ODBC 17 e o ODBC 18 instalados, PDO_SQLSRV pode associar-se à versão mais antiga. As versões antigas ODBC 17.x não conhecem valores mais recentes Authentication como ActiveDirectoryServicePrincipal ou ActiveDirectoryDefault, e até ActiveDirectoryMsi requerem ODBC 17.3.1.1 ou uma versão posterior.
Correção:
Afixe o driver no DSN:
<?php
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;" .
"Encrypt=true;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
A forma entre parênteses ({ODBC Driver 18 for SQL Server}) escapa dos espaços no nome do driver. A própria mensagem de erro indica sempre o driver que o comunicou, pelo que o prefixo [Microsoft][ODBC Driver 17 for SQL Server] na mensagem de erro é a forma mais rápida de confirmar que foi associado o driver errado.
A palavra-chave inválida 'UID' foi especificada na cadeia DSN
Sintomas:
SQLSTATE[IMSSP]: An invalid keyword 'UID' was specified in the DSN string.
Motivo:
PDO_SQLSRV impõe uma lista de permissões de palavras‑chave de DSN e não aceita UID nem PWD na DSN. O PDO reserva o segundo e o terceiro argumentos do construtor para esse efeito, e o PDO_SQLSRV traduz internamente esses argumentos em ODBC UID/PWD.
Correção:
Mova o nome de utilizador (e a palavra-passe, para autenticação SQL) para o construtor PDO:
<?php
// SQL authentication.
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;Encrypt=true";
$conn = new PDO($dsn, $user, $password);
// User-assigned managed identity. Pass the identity's client ID as $username.
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=$server;Database=$db;" .
"Encrypt=true;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, $clientId, null);
O controlador procedural SQLSRV, em contrapartida, aceita UID e PWD no array de opções de ligação passado para sqlsrv_connect().
PDO_SQLSRV ignora silenciosamente o AccessToken no array de opções
Sintoma:
Tem um token de acesso do Microsoft Entra (por exemplo, de az account get-access-token --resource https://database.windows.net/, ManagedIdentityCredential ou ClientSecretCredential) e passa-o ao PDO_SQLSRV como ['AccessToken' => $token] no quarto argumento do construtor. A tentativa de ligação falha com um erro confuso como Windows logins are not supported in this version of SQL Server ou Login failed for user '', como se não tivessem sido fornecidas credenciais.
Motivo:
O quarto argumento construtor do PDO é reservado para constantes de atributo específicas do driver (chaves inteiras como PDO::ATTR_ERRMODE). O PDO deixa cair silenciosamente entradas com chaves de string, como AccessToken, por isso PDO_SQLSRV nunca vê o token. A ligação volta então à autenticação integrada do Windows, que o servidor rejeita.
Correção:
Passa AccessToken para a cadeia DSN. Restringa a matriz de opções a constantes PDO::ATTR_*.
<?php
$server = '<server>.database.windows.net';
$token = getenv('SQL_ACCESS_TOKEN'); // raw JWT, no "Bearer " prefix
$dsn = "sqlsrv:Server=$server;Database=<database>;Encrypt=true;AccessToken=$token";
$conn = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Para exemplos adicionais de autenticação Microsoft Entra, incluindo o formulário DSN para PDO_SQLSRV, veja Conectar usando autenticação Microsoft Entra.
No SQLSRV procedural, AccessToken pertence ao array de informações de ligação passado a sqlsrv_connect(), que encapsula o JWT em bruto em SQL_COPT_SS_ACCESS_TOKEN por si:
<?php
$server = '<server>.database.windows.net';
$token = getenv('SQL_ACCESS_TOKEN'); // raw JWT, no "Bearer " prefix
$connectionInfo = [
'Database' => '<database>',
'AccessToken' => $token,
'Encrypt' => true,
'TrustServerCertificate' => false,
'Driver' => '{ODBC Driver 18 for SQL Server}',
];
$conn = sqlsrv_connect($server, $connectionInfo);
if ($conn === false) {
print_r(sqlsrv_errors());
exit(1);
}
Erros de certificado TLS
Sintomas:
SQLSTATE[08001]: SSL Provider: The certificate chain was issued by an authority that is not trusted
SQLSTATE[08001]: SSL Provider: The target principal name is incorrect
Soluções:
Prefira um certificado de confiança. Usa TrustServerCertificate=true apenas para desenvolvimento local contra um servidor que controlas.
Para desenvolvimento com um certificado autoassinado:
<?php
$server = 'localhost';
$database = '<database>';
$user = '<user_id>';
$password = '<password>';
$dsn = "sqlsrv:Server=$server;Database=$database;Encrypt=true;TrustServerCertificate=true";
$conn = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Caution
TrustServerCertificate=true Desativa a validação do certificado do servidor. Nunca leves esse cenário para produção, encenação ou ambientes partilhados.
Para um hostname de produção que não corresponde ao Nome Comum do certificado (por exemplo, ao estabelecer ligação através de um listener), especifique o sujeito real do certificado:
<?php
$dsn = "sqlsrv:Server=<listener>;Database=<database>;Encrypt=true;HostNameInCertificate=*.database.windows.net;Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Tempo limite de ligação
Sintomas:
SQLSTATE[HYT00]: Login timeout expired
Possíveis causas e soluções:
-
LoginTimeoutnão definido ou definido para um valor demasiado baixo para ativação pós-falha a frio. Defina um valor explícito deLoginTimeout(em segundos) no DSN ao estabelecer ligação ao SQL do Azure. Os failovers em grupos de failover e bases de dados de arranque a frio podem demorar mais do que um curto timeout do lado do cliente permite. Consulte Opções de Ligação para a referência de opções. -
Limite de reconexão por inatividade truncado. Se definires
ConnectRetryCounteConnectRetryInterval, certifica-te de queLoginTimeout >= ConnectRetryCount * ConnectRetryInterval. Caso contrário, o tempo limite de login termina o ciclo de reconexão mais cedo. Ver resiliência da ligação ociosa.
<?php
$dsn = "sqlsrv:Driver={ODBC Driver 18 for SQL Server};Server=<server>.database.windows.net;Database=<database>;" .
"Encrypt=true;LoginTimeout=90;ConnectRetryCount=5;ConnectRetryInterval=15;" .
"Authentication=ActiveDirectoryMsi";
$conn = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Problemas de execução de consultas
Falhas silenciosas com PDO
Sintoma:
Uma chamada a PDO::exec() ou PDOStatement::execute() devolve false, mas não gera uma exceção.
Correção:
Com o PHP 8.0 e versões posteriores, o modo de erro PDO predefinido é PDO::ERRMODE_EXCEPTION. Se uma chamada for retornada false sem ser lançada, a aplicação alterou o modo para PDO::ERRMODE_SILENT ou PDO::ERRMODE_WARNING. Volte a colocar o modo de exceção para que as falhas gerem exceções:
<?php
$conn = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Se não conseguires mudar o modo globalmente, verifica $conn->errorInfo() (ou $stmt->errorInfo()) após cada chamada. O array contém [SQLSTATE, driver code, driver message].
Nome do objeto inválido
Sintomas:
SQLSTATE[42S02]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Invalid object name 'Products'.
Possíveis causas e soluções:
Contexto errado na base de dados. Confirme com uma pergunta rápida:
<?php $stmt = $conn->query("SELECT DB_NAME()"); echo $stmt->fetchColumn();Falta-lhe o qualificador de esquema. Use nomes totalmente qualificados para evitar depender do esquema padrão do chamador:
SELECT * FROM dbo.Products;Sensibilidade a maiúsculas e minúsculas. As bases de dados criadas com uma ordenação sensível a maiúsculas/minúsculas consideram
productseProductscomo objetos diferentes. Corresponde exatamente ao caso na definição da tabela.
Número errado de parâmetros
Sintomas:
SQLSTATE[HY093]: Invalid parameter number
SQLSTATE[07002]: COUNT field incorrect or syntax error
Correção:
Para PDO_SQLSRV, o número de marcadores de posição ? tem de corresponder ao número de valores que passa para execute(), e cada ? associa um único escalar (não um array). Para parâmetros nomeados, cada :name no SQL tem de aparecer no array, e vice-versa.
<?php
$stmt = $conn->prepare(
"SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?"
);
$stmt->execute([1, 50.0]);
foreach ($stmt as $row) {
// ...
}
Para SQLSRV, passe o array de parâmetros para sqlsrv_query() ou sqlsrv_prepare():
<?php
$stmt = sqlsrv_query(
$conn,
"SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?",
[1, 50.0]
);
if ($stmt === false) {
die(print_r(sqlsrv_errors(), true));
}
Para uma introdução mais abrangente à ligação de parâmetros, veja Executar consultas parametrizadas.
As instruções preparadas emuladas do PDO mascaram erros
Sintomas:
Uma instrução corre com sucesso numa ligação, mas gera um erro de sintaxe noutra ligação que utiliza o mesmo texto de consulta.
Motivo:
PDO_SQLSRV suporta tanto declarações preparadas emuladas como nativas. As instruções prepare emuladas (PDO::ATTR_EMULATE_PREPARES = true) interpolam parâmetros no lado do cliente. As preparações nativas (false) enviam a consulta e os parâmetros separadamente para o servidor. O comportamento difere para TOP (?), parâmetros com valor de tabela e alguns casos-limite na coerção de tipos.
Correção:
Prefiro preparações nativas em produção. Defina PDO::ATTR_EMULATE_PREPARES => false no momento da ligação para que o comportamento seja consistente entre os ambientes:
<?php
$conn = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
]);
Para mais detalhes sobre quando utilizar cada modo, consulte PDO::prepare.
Problemas de tipos de dados
Os caracteres Unicode aparecem como ? ou distorcidos
Sintomas:
As linhas que o PHP escreve contêm pontos de interrogação ou caracteres de substituição em vez dos caracteres originais não ASCII. As leituras devolvem texto distorcido.
Possíveis causas e soluções:
O tipo de coluna é VARCHAR, não NVARCHAR. As colunas varchar usam uma página de códigos, não Unicode. Use nvarchar para texto internacionalizado.
Falta uma dica de codificação UTF-8 no PDO_SQLSRV. Quando a tua coluna do SQL Server for nvarchar e os teus dados em PHP forem UTF-8, informa o controlador para converter entre UTF-8 (cliente) e UTF-16 (servidor):
<?php $conn = new PDO( "sqlsrv:Server=<server>;Database=<database>;Encrypt=true", $user, $password, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8, ] );Controlador SQLSRV: pedir UTF-8 de forma explícita.
SQLSRV_ENC_CHARé a página de código do sistema padrão de 8 bits, não UTF-8. Para UTF-8 com SQLSRV, defina"CharacterSet" => "UTF-8"na ligação e passe o literal'UTF-8'paraSQLSRV_PHPTYPE_STRINGao obter ou associar. Veja Enviar e recuperar dados UTF-8.
Erros de conversão de data e hora
Sintomas:
SQLSTATE[22007]: Invalid character value for cast specification
Correção:
No PDO_SQLSRV, não associes um objeto raw DateTime. O PDO converte os valores associados em string antes da associação, e o DateTime do PHP não tem o método __toString(), pelo que execute([new DateTime(...)]) gera Object of class DateTime could not be converted to string. Formate primeiro o valor, ou passe uma cadeia ISO 8601 (YYYY-MM-DD HH:MM:SS[.fff]), que não seja uma cadeia formatada localmente.
<?php
$stmt = $conn->prepare("INSERT INTO dbo.Events (EventDate) VALUES (?)");
$stmt->execute([(new DateTime("2026-03-15 10:00:00"))->format("Y-m-d H:i:s.u")]);
Para obter colunas datetime como objetos DateTime em vez de cadeias de caracteres no PDO_SQLSRV, defina o atributo da instrução:
<?php
$stmt = $conn->prepare("SELECT EventDate FROM dbo.Events");
$stmt->setAttribute(PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, true);
$stmt->execute();
Para mais detalhes, consulte Recuperar objetos datetime (PDO_SQLSRV).
Problemas de formatação decimal
Sintomas:
Os valores entre -1 e 1 não têm um zero à frente, ou os valores de dinheiro e dinheiro pequeno mostram um número inesperado de casas decimais.
Correção:
PDO_SQLSRV obtém sempre valores decimais e numéricos como cadeias com a sua precisão e escala exatas. Defina PDO::SQLSRV_ATTR_FORMAT_DECIMALS para adicionar um zero à esquerda aos valores entre -1 e 1:
<?php
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);
PDO::SQLSRV_ATTR_DECIMAL_PLACES Aplica-se apenas ao dinheiro e aos valores de dinheiro pequeno . Define a escala apresentada de 0 a 4 e pode arredondar o valor apresentado. Não afeta valores decimais ou numéricos .
Para mais detalhes, veja Formatar decimais e dinheiro (PDO_SQLSRV) ou Formatar decimais e dinheiro (SQLSRV).
Problemas de transação
As alterações nos dados não persistem
Sintomas:
As linhas que inseres ou atualizas no PHP não aparecem quando consultas a partir de outra sessão.
Motivo:
PDO::beginTransaction() abre uma transação explícita que requer um commit(). Se o script PHP terminar sem chamar commit(), o PDO anula a transação durante o encerramento da ligação.
Correção:
Associe sempre beginTransaction() a commit(), e use try/catch para reverter em caso de erro:
<?php
try {
$conn->beginTransaction();
$conn->exec("INSERT INTO dbo.Orders (CustomerID, Total) VALUES (1, 100)");
$conn->exec("UPDATE dbo.Inventory SET Stock = Stock - 1 WHERE ProductID = 5");
$conn->commit();
} catch (PDOException $e) {
$conn->rollBack();
throw $e;
}
Para SQLSRV, utilize sqlsrv_begin_transaction, sqlsrv_commit e sqlsrv_rollback.
Erros de bloqueio
Sintomas:
SQLSTATE[40001]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Transaction (Process ID 62) was deadlocked
Correção:
Trate erros transitórios de deadlock com lógica de repetição. Envolve toda a transação (não apenas a instrução que falha) para que as instruções anteriores sejam repetidas na nova transação. Para um padrão de retentativas orientado para produção, consulte o exemplo na página inicial do driver PHP.
Bloqueios recorrentes indicam um problema de design. Capture o gráfico de deadlock e analise quais as instruções e tipos de bloqueio envolvidos. Correções comuns incluem reordenação das operações para que transações concorrentes adquiram bloqueios na mesma sequência, redução do âmbito das transações e adição de índices para diminuir a duração dos bloqueios. Para uma explicação detalhada, consulte o guia de Deadlocks.
Problemas de resiliência da ligação
A ligação não é restabelecida
Sintomas:
Uma ligação idle mantém-se quebrada após um failover do Base de Dados SQL do Azure, mesmo que tenhas definido ConnectRetryCount e ConnectRetryInterval.
Possíveis causas e soluções:
-
Cursor ativo do lado do servidor. A resiliência de conexões inativas apenas restabelece conexões inativas. Um cursor aberto do lado do servidor ou uma transação pendente mantém a ligação ativa. Liberte os cursores no servidor utilizando
sqlsrv_free_stmt()ou$stmt = null;(PDO) antes da janela de failover, ou mude para um cursor com buffer no cliente. Ver resiliência da ligação ociosa. -
Estado de sessão não recuperável. Alguns estados da sessão não podem ser restabelecidos, incluindo tabelas temporárias, cursores globais e locais, contexto de transação, bloqueios de aplicação,
EXECUTE AS/REVERT, identificadores de automatização OLE, identificadores XML preparados e sinalizadores de rastreio. Qualquer um destes estados de sessão impede a reconexão automática. -
LoginTimeoutdemasiado pequeno. SeConnectRetryCount * ConnectRetryInterval > LoginTimeout, o condutor para de tentar novamente quandoLoginTimeouté alcançado. AumenteLoginTimeoutpara cobrir a totalidade do orçamento de repetições.
Problemas de desempenho
Para o diagnóstico e a resolução de consultas lentas, arranques iniciais, conjuntos de resultados extensos e inserções em massa, consulte Otimização do desempenho.
Ativar diagnóstico de controlador
Quando as chamadas ao nível error_log() da aplicação não fornecem informação suficiente, ative o registo do lado do condutor. Reporta todas as chamadas ODBC feitas pelo motorista.
PDO_SQLSRV
Defina pdo_sqlsrv.log_severity em php.ini e reinicie o servidor web. Esta configuração só é legível na inicialização:
[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1
Os valores são 0 (desligado, o padrão), -1 (erros, avisos e avisos), 1 (erros), 2 (avisos) e 4 (avisos).
SQLSRV
Ativar o registo em tempo de execução com sqlsrv_configure():
<?php
sqlsrv_configure("LogSubsystems", SQLSRV_LOG_SYSTEM_CONN | SQLSRV_LOG_SYSTEM_STMT);
sqlsrv_configure("LogSeverity", SQLSRV_LOG_SEVERITY_ERROR | SQLSRV_LOG_SEVERITY_WARNING);
As entradas de registo vão para o ficheiro configurado por error_log em php.ini. Para obter a lista completa de subsistemas e níveis de gravidade, consulte Atividade de registo.
Problemas de containers e CI
Bibliotecas de sistema em falta no Linux
Sintomas:
error while loading shared libraries: libodbc.so.2: cannot open shared object file
error while loading shared libraries: libssl.so.1.1: cannot open shared object file
Correção:
Instale as dependências em tempo de execução antes de instalar o driver PHP:
| Distribution | Comando de Instalação |
|---|---|
| Ubuntu e Debian | sudo apt-get install unixodbc libgssapi-krb5-2 |
| Red Hat e Fedora | sudo dnf install unixODBC krb5-libs |
| Alpine | apk add unixodbc gcompat |
Depois instala msodbcsql18 a partir do repositório de pacotes da Microsoft. Para repositórios e versões de pacotes específicos de distribuição, consulte o guia de instalação de drivers ODBC.
As compilações da imagem Docker são bem-sucedidas, mas as ligações falham em tempo de execução
Sintomas:
A imagem é criada e o PHP inicia, mas PDO::__construct() apresenta um erro de controlador ODBC não encontrado.
Correção:
Verifique se o driver ODBC está instalado na imagem de runtime, não apenas na fase de compilação. Instalar msodbcsql18 e unixodbc-dev na mesma fase de entrega para produção. Numa construção em várias etapas, instale-as na fase final. Uma instalação baseada em Debian de estágio único é a seguinte:
# Pin to a specific PHP minor version in production, for example php:8.4.11-cli.
FROM php:8.4-cli
RUN apt-get update && apt-get install -y --no-install-recommends \
curl gnupg2 apt-transport-https ca-certificates \
&& curl -sSL https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > /usr/share/keyrings/microsoft.gpg \
&& echo "deb [arch=amd64 signed-by=/usr/share/keyrings/microsoft.gpg] https://packages.microsoft.com/debian/12/prod bookworm main" > /etc/apt/sources.list.d/mssql-release.list \
&& apt-get update \
&& ACCEPT_EULA=Y apt-get install -y --no-install-recommends msodbcsql18 unixodbc-dev \
# $PHPIZE_DEPS ships in the official php image and includes gcc, make, autoconf, and re2c.
&& apt-get install -y --no-install-recommends $PHPIZE_DEPS \
&& pecl install sqlsrv pdo_sqlsrv \
&& docker-php-ext-enable sqlsrv pdo_sqlsrv \
&& apt-get purge -y --auto-remove $PHPIZE_DEPS \
&& rm -rf /var/lib/apt/lists/*