Nota:
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Diagnostica y resuelve problemas comunes cuando uses los controladores de Microsoft para PHP para SQL Server para conectarte a SQL Server, Azure SQL Database, Azure SQL Managed Instance y la base de datos SQL en Microsoft Fabric.
Para patrones generales de gestión de errores y advertencias, véase Gestión de errores y advertencias. Para la captura de diagnósticos del lado del controlador, consulte Registro de actividad.
Problemas de instalación
Extensión no cargada
Síntomas:
-
phpinfo()no incluye una secciónsqlsrvnipdo_sqlsrv. -
PDOException: could not find driveral crear unPDOcon el DSNsqlsrv:. -
Fatal error: Uncaught Error: Call to undefined function sqlsrv_connect().
Posibles causas y soluciones:
-
Extensión no activada en php.ini. Verifica que tanto
extension=sqlsrvcomoextension=pdo_sqlsrvestén descomentados. En Windows, usa el nombre completo del archivo (extension=php_sqlsrv_84_ts_x64.dll). Para obtener más información, consulta Carga de los controladores. -
Configuración de seguridad de rosca incorrecta. El binario del controlador debe coincidir con la seguridad de subprocesos de tu compilación de PHP (
tspara seguro de subprocesos,ntspara no seguro de subprocesos). Ejecutephp -i | grep "Thread Safety"para comprobarlo. Descarga el binario correspondiente desde la página de descarga. -
Falta el controlador ODBC de Microsoft. Los controladores PHP encapsulan el Microsoft ODBC Driver for SQL Server. En Linux y macOS, instala
msodbcsql18(omsodbcsql17) con tu gestor de paquetes antes de cargar las extensiones. En Windows, instala el controlador ODBC desde la página de descarga.
Verifica si la instalación es exitosa:
php -m | grep -i sqlsrv
Deberías ver ambos pdo_sqlsrv y sqlsrv en la salida.
Falla la instalación de PECL en Linux o macOS
Síntomas:
error: ‘SQL_HANDLE_DBC’ undeclared (first use in this function)
fatal error: 'sql.h' file not found
Corrección:
Instala los encabezados de desarrollo ODBC antes de ejecutar pecl install:
-
Ubuntu y Debian:
sudo apt-get install unixodbc-dev -
Red Hat, Fedora y CentOS:
sudo dnf install unixODBC-devel -
Alpine:
apk add unixodbc-dev -
macOS:
brew install unixodbc
Luego vuelve a intentarlo:
sudo pecl install sqlsrv
sudo pecl install pdo_sqlsrv
Si pecl sigue fallando después de que se hayan instalado los archivos de cabecera, es posible que la cadena de herramientas de compilación esté incompleta. Instala phpize, re2c, y un compilador en C++ (build-essential en Debian y Ubuntu, gcc-c++ make en Red Hat y Fedora, en build-base Alpine).
Para la ruta completa de instalación, consulta el tutorial de instalación para Linux y macOS.
Varias versiones de PHP instaladas
Síntomas:
phpinfo() en tu servidor web muestra una versión de PHP, pero php -v en la línea de comandos aparece otra, y el controlador aparece cargado solo en una de ellas.
Corrección:
Cada versión de PHP tiene sus propios directorios php.ini y ext. Localiza el archivo de configuración correcto con php --ini dentro del entorno al que le falta el controlador, y añade allí las líneas extension=. Reinicia el servidor web (Apache, Nginx + PHP-FPM o IIS) tras cualquier cambio php.ini.
Problemas de conexión
No se puede conectar al servidor
Síntomas:
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
Posibles causas y soluciones:
El servidor no es accesible. Comprueba que el nombre del servidor y el puerto sean correctos. Desde el host PHP, prueba la conectividad TCP en bruto.
# Linux and macOS nc -vz <server>.database.windows.net 1433 # Windows PowerShell Test-NetConnection -ComputerName <server>.database.windows.net -Port 1433El cortafuegos bloquea la salida 1433. Los cortafuegos corporativos y los NSGs en la nube suelen bloquear el puerto saliente 1433. Añade una excepción o permite los rangos de IP de Azure SQL Database para tu región.
Azure SQL server firewall. Añade la IP pública de tu cliente a las reglas del firewall a nivel de servidor en el portal de Azure.
Instancia con nombre. Para una instancia nombrada, verifica que el servicio SQL Server Browser está funcionando en el servidor y que UDP 1434 está abierto. O bien, conecta por puerto en vez de por nombre de la instancia.
Error de inicio de sesión
Síntomas:
SQLSTATE[28000]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Login failed for user '<user_id>'.
Posibles causas y soluciones:
- Modo de autenticación SQL desactivado. Las instancias locales de SQL Server solo usan autenticación de Windows por defecto. Activa la autenticación en modo mixto en SQL Server Management Studio bajo Propiedades>del servidor Seguridad y luego reinicia el servicio SQL Server.
-
Azure SQL credentials format. Azure SQL requiere el nombre de usuario totalmente cualificado (
user@servername) al conectarse desde herramientas que no lo añaden automáticamente. - El usuario no está asignado a la base de datos. Verifica que el inicio de sesión tenga un mapa de usuario en la base de datos de destino y que el usuario tenga los permisos requeridos.
-
Prefiero Microsoft Entra ID. Para Azure SQL, Azure SQL Managed Instance y la base de datos SQL en Fabric, utiliza la autenticación de Microsoft Entra (
Authentication=ActiveDirectoryMsi,Authentication=ActiveDirectoryServicePrincipalo un token de acceso) en lugar de los inicios de sesión de SQL. Consulte Conexión mediante la autenticación de Microsoft Entra.
Valor inválido especificado para el atributo de cadena de conexión 'Authentication'
Síntomas:
SQLSTATE[08001]: [Microsoft][ODBC Driver 17 for SQL Server]Invalid value specified for connection string attribute 'Authentication'
Causa:
El controlador ODBC informa del error, pero el verdadero problema es a qué controlador está vinculado PDO_SQLSRV. Si la DSN no incluye una Driver= palabra clave y el host tiene ODBC 17 y ODBC 18 instalados, PDO_SQLSRV puede vincular a la versión anterior. Las versiones antiguas de ODBC 17.x no conocen valores más recientes Authentication como ActiveDirectoryServicePrincipal o ActiveDirectoryDefault, e incluso ActiveDirectoryMsi requieren ODBC 17.3.1.1 o una versión posterior.
Corrección:
Fija el controlador en el 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]);
La forma entre corchetes ({ODBC Driver 18 for SQL Server}) escapa los espacios del nombre del controlador. El propio mensaje de error siempre nombra al controlador que lo informó, por lo que el prefijo [Microsoft][ODBC Driver 17 for SQL Server] del error es la forma más rápida de confirmar que se vinculó el controlador incorrecto.
La palabra clave inválida 'UID' se especificó en la cadena DSN
Síntomas:
SQLSTATE[IMSSP]: An invalid keyword 'UID' was specified in the DSN string.
Causa:
PDO_SQLSRV aplica una lista de palabras clave de DSN permitidas y no acepta UID ni PWD en el DSN. PDO reserva los argumentos del segundo y tercer constructor para esos, y PDO_SQLSRV los traduce internamente a ODBC UID/PWD .
Corrección:
Mueve el nombre de usuario (y la contraseña, para autenticación SQL) al constructor 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);
El controlador procedimental SQLSRV, en cambio, acepta UID y PWD en la matriz de opciones de conexión pasada a sqlsrv_connect().
PDO_SQLSRV ignora silenciosamente AccessToken en el array de opciones
Síntoma:
Tienes un token de acceso de Microsoft Entra (por ejemplo, de az account get-access-token --resource https://database.windows.net/, ManagedIdentityCredential o ClientSecretCredential), y se lo pasas a PDO_SQLSRV como ['AccessToken' => $token] en el cuarto argumento del constructor. El intento de conexión falla con un error confuso como Windows logins are not supported in this version of SQL Server o Login failed for user '', como si no se hubieran proporcionado credenciales.
Causa:
El cuarto argumento constructor de PDO está reservado para constantes de atributos específicas del controlador (claves enteras como PDO::ATTR_ERRMODE). PDO elimina silenciosamente entradas con clave de cadena como AccessToken, por lo que nunca PDO_SQLSRV ve el token. La conexión entonces vuelve a la autenticación integrada de Windows, que el servidor rechaza.
Corrección:
Inserta AccessToken en la cadena DSN. Reserve la matriz de opciones para las constantes de 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 ejemplos adicionales de autenticación Microsoft Entra, incluido el formulario DSN para PDO_SQLSRV, véase Conectar usando autenticación Microsoft Entra.
En el caso de SQLSRV procedimental, AccessToken debe ir en la matriz de información de conexión que se pasa a sqlsrv_connect(), que se encarga de envolver el JWT sin procesar en SQL_COPT_SS_ACCESS_TOKEN por ti:
<?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);
}
Errores en el certificado TLS
Síntomas:
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
Soluciones:
Prefiero un certificado de confianza. Úsalo TrustServerCertificate=true solo para desarrollo local contra un servidor que controlas.
Para el desarrollo con un certificado autofirmado:
<?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 Desactiva la validación del certificado del servidor. Nunca lleves ese escenario a la producción, la puesta en escena o en entornos compartidos.
Para un nombre de host de producción que no coincide con el Nombre Común del certificado (por ejemplo, al conectarse a través de un listener), especifica el sujeto real del 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,
]);
Tiempo de espera de conexión
Síntomas:
SQLSTATE[HYT00]: Login timeout expired
Posibles causas y soluciones:
-
LoginTimeoutno está configurado o está configurado en un valor demasiado bajo para la conmutación por error en frío . Establece un valor explícito deLoginTimeout(en segundos) en el DSN al conectarse con Azure SQL. Las conmutaciones por error de grupos de conmutación por error y las bases de datos de arranque en frío pueden tardar más de lo que permite un tiempo de espera corto del lado del cliente. Consulta Opciones de conexión para la referencia de opciones. -
Presupuesto de reconexión en inactividad truncado. Si configuras
ConnectRetryCountyConnectRetryInterval, asegúrate de queLoginTimeout >= ConnectRetryCount * ConnectRetryInterval. De lo contrario, el tiempo de espera de inicio de sesión termina el bucle de reconexión antes de tiempo. Consulte resiliencia de conexión inactiva.
<?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 ejecución de consultas
Fallos silenciosos con PDO
Síntoma:
Una llamada a PDO::exec() o PDOStatement::execute() devuelve false, pero no lanza una excepción.
Corrección:
Con PHP 8.0 y versiones posteriores, el modo de error PDO por defecto es PDO::ERRMODE_EXCEPTION. Si una llamada regresa false sin lanzarla, la aplicación cambia el modo a PDO::ERRMODE_SILENT o PDO::ERRMODE_WARNING. Vuelve a ponerlo en modo excepción para que los fallos generen excepciones:
<?php
$conn = new PDO($dsn, $user, $password, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
]);
Si no puedes cambiar el modo globalmente, comprueba $conn->errorInfo() (o $stmt->errorInfo()) después de cada llamada. El array contiene [SQLSTATE, driver code, driver message].
Nombre de objeto no válido.
Síntomas:
SQLSTATE[42S02]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Invalid object name 'Products'.
Posibles causas y soluciones:
Contexto incorrecto de la base de datos. Verifica con una consulta rápida:
<?php $stmt = $conn->query("SELECT DB_NAME()"); echo $stmt->fetchColumn();Falta el calificador de esquema. Utiliza nombres totalmente calificados para evitar depender del esquema predeterminado del llamante:
SELECT * FROM dbo.Products;Distinción entre mayúsculas y minúsculas. Las bases de datos creadas con una colación que distingue entre mayúsculas y minúsculas tratan
productsyProductscomo objetos diferentes. Haz coincidir exactamente las mayúsculas y minúsculas de la definición de la tabla.
Número incorrecto de parámetros
Síntomas:
SQLSTATE[HY093]: Invalid parameter number
SQLSTATE[07002]: COUNT field incorrect or syntax error
Corrección:
En PDO_SQLSRV, el número de marcadores de posición ? debe coincidir con el número de valores que pasas a execute(), y cada ? vincula un único escalar (no un array). Para parámetros nombrados, cada :name en el SQL debe aparecer en el array y viceversa.
<?php
$stmt = $conn->prepare(
"SELECT * FROM dbo.Products WHERE CategoryID = ? AND ListPrice > ?"
);
$stmt->execute([1, 50.0]);
foreach ($stmt as $row) {
// ...
}
Para SQLSRV, pasa el array de parámetros a sqlsrv_query() o 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 una introducción más amplia a la vinculación de parámetros, véase Realizar consultas parametrizadas.
Los preparativos emulados de PDO enmascaran los errores
Síntomas:
Una instrucción se ejecuta correctamente en una conexión pero genera un error de sintaxis en otra conexión que utiliza el mismo texto de consulta.
Causa:
PDO_SQLSRV soporta tanto declaraciones preparadas emuladas como nativas. Los preparativos emulados (PDO::ATTR_EMULATE_PREPARES = true) interpolan los parámetros del lado del cliente. Los preparadores nativos (false) envían la consulta y los parámetros por separado al servidor. El comportamiento varía para TOP (?), los parámetros con valores de tabla y algunos casos extremos de conversión de tipos.
Corrección:
Es preferible utilizar preparaciones nativas en producción. Configura PDO::ATTR_EMULATE_PREPARES => false en tiempo de conexión para que el comportamiento sea consistente entre los entornos:
<?php
$conn = new PDO($dsn, null, null, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false,
]);
Para más detalles sobre cuándo usar cada modo, véase PDO::prepare.
Problemas con tipos de datos
Los caracteres Unicode aparecen como ? o distorsionados
Síntomas:
Las filas que escribe PHP contienen signos de interrogación o caracteres de reemplazo en lugar de los caracteres originales no ASCII. Las lecturas devuelven texto ilegible.
Posibles causas y soluciones:
El tipo de columna es VARCHAR, no NVARCHAR. Las columnas varchar usan una página de códigos, no Unicode. Usa nvarchar para textos internacionalizados.
Falta la pista de codificación UTF-8 en PDO_SQLSRV. Cuando tu columna de SQL Server sea nvarchar y tus datos PHP sean UTF-8, dile al controlador que convierta entre UTF-8 (cliente) y 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: solicitar UTF-8 explícitamente.
SQLSRV_ENC_CHARes la página de códigos del sistema predeterminada de 8 bits, no UTF-8. Para UTF-8 con SQLSRV, configura"CharacterSet" => "UTF-8"en la conexión y pasa el literal'UTF-8'aSQLSRV_PHPTYPE_STRINGal recuperar o vincular. Consulta Enviar y recuperar datos UTF-8.
Errores de conversión de fecha y hora
Síntomas:
SQLSTATE[22007]: Invalid character value for cast specification
Corrección:
En PDO_SQLSRV, no encuantes un objeto en bruto DateTime . PDO convierte los valores vinculados en cadenas antes de vincularlos, y DateTime de PHP no tiene ningún método __toString(), por lo que execute([new DateTime(...)]) lanza Object of class DateTime could not be converted to string. Formatea primero el valor o pasa una cadena ISO 8601 (YYYY-MM-DD HH:MM:SS[.fff]), no una cadena formateada por localidad.
<?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 obtener las columnas datetime como objetos DateTime en lugar de cadenas en PDO_SQLSRV, establece el atributo de la instrucción:
<?php
$stmt = $conn->prepare("SELECT EventDate FROM dbo.Events");
$stmt->setAttribute(PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE, true);
$stmt->execute();
Para más detalles, véase Recuperar objetos de fecha y hora (PDO_SQLSRV).
Problemas de formato decimal
Síntomas:
Los valores entre -1 y 1 carecen de un cero inicial, o los valores de dinero y dinero pequeño muestran un número inesperado de decimales.
Corrección:
PDO_SQLSRV siempre obtiene valores decimales y numéricos como cadenas con su precisión y escala exactas. Establece PDO::SQLSRV_ATTR_FORMAT_DECIMALS para añadir un cero inicial a los valores entre -1 y 1:
<?php
$conn->setAttribute(PDO::SQLSRV_ATTR_FORMAT_DECIMALS, true);
PDO::SQLSRV_ATTR_DECIMAL_PLACES Se aplica solo al dinero y a los valores de dinero pequeño . Establece la escala mostrada del 0 al 4 y puede redondear el valor mostrado. No afecta a los valores decimales ni numéricos .
Para más detalles, véase Formatear decimales y dinero (PDO_SQLSRV) o Formatear decimales y dinero (SQLSRV).
Problemas de transacción
Los cambios en los datos no persisten
Síntomas:
Las filas que insertas o actualizas en PHP no aparecen cuando consultas desde otra sesión.
Causa:
PDO::beginTransaction() abre una transacción explícita que requiere un commit() explícito. Si el script de PHP finaliza sin llamar a commit(), PDO revierte la transacción durante la limpieza de la conexión.
Corrección:
Combina siempre beginTransaction() con commit() y usa try/catch para revertir en caso de error:
<?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, usa sqlsrv_begin_transaction, sqlsrv_commit y sqlsrv_rollback.
Errores de interbloqueo
Síntomas:
SQLSTATE[40001]: [Microsoft][ODBC Driver 18 for SQL Server][SQL Server]Transaction (Process ID 62) was deadlocked
Corrección:
Gestiona errores de bloqueo transitorio con lógica de reintentos. Envuelve toda la transacción (no solo la instrucción que falla) para que las instrucciones anteriores se repitan en la nueva transacción. Para un patrón de reintentos orientado a producción, consulta el ejemplo en la página de inicio del controlador PHP.
Los bloqueos recurrentes indican un problema de diseño. Captura el gráfico de interbloqueo y analiza qué instrucciones y tipos de bloqueo están implicados. Las soluciones comunes incluyen reordenar operaciones para que las transacciones competidoras adquieran bloqueos en la misma secuencia, reducir el alcance de la transacción y añadir índices para disminuir la duración del bloqueo. Para una guía completa, consulta la guía de Deadlocks.
Problemas de resiliencia de conexión
No se produce la reconexión
Síntomas:
Una conexión inactiva permanece interrumpida tras una conmutación por error de Azure SQL Database, aunque se configuren ConnectRetryCount y ConnectRetryInterval.
Posibles causas y soluciones:
-
Cursor activo en el lado del servidor. La resiliencia de las conexiones inactivas solo reconecta conexiones inactivas . Un cursor abierto en el lado del servidor o una transacción pendiente mantiene la conexión activa. Libere los cursores del servidor mediante
sqlsrv_free_stmt()o$stmt = null;(PDO) antes de la ventana de conmutación por error, o cambie a un cursor del cliente con búfer. Consulte resiliencia de conexión inactiva. -
Estado de sesión no recuperable. No se pueden restablecer algunos elementos del estado de la sesión, incluidas las tablas temporales, los cursores globales y locales, el contexto de la transacción, los bloqueos de aplicación,
EXECUTE AS/REVERT, los identificadores de automatización OLE, los identificadores XML preparados y los indicadores de seguimiento. Cualquiera de estos estados de sesión impide la reconexión automática. -
LoginTimeoutDemasiado pequeña. Si se estableceConnectRetryCount * ConnectRetryInterval > LoginTimeout, el controlador deja de reintentar cuando se alcanzaLoginTimeout. AumentaLoginTimeoutpara cubrir todo el presupuesto de reintentos.
Problemas de rendimiento
Para el diagnóstico y la resolución de consultas lentas, arranques en frío, grandes conjuntos de resultados e inserciones masivas, véase Optimización del rendimiento.
Habilitar diagnóstico de controladores
Cuando las llamadas en el nivel de aplicación error_log() no proporcionen suficiente información, activa el registro por parte del controlador. Informa de cada llamada ODBC que hace el conductor.
PDO_SQLSRV
Configura pdo_sqlsrv.log_severity en php.ini y reinicia el servidor web. Esta configuración solo es legible al inicializar:
[pdo_sqlsrv]
pdo_sqlsrv.log_severity = 1
Los valores son 0 (desactivado, el predeterminado), -1 (errores, advertencias y avisos), 1 (errores), 2 (advertencias) y 4 (avisos).
SQLSRV
Activar el registro en tiempo de ejecución con 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);
Las entradas de registro van al archivo configurado por error_log en php.ini. Para consultar la lista completa de subsistemas y niveles de gravedad, véase actividad de registro.
Problemas de contenedor y de CI
Bibliotecas del sistema ausentes en Linux
Síntomas:
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
Corrección:
Instala las dependencias de ejecución antes de instalar el controlador PHP:
| Distribution | Comando de instalación |
|---|---|
| Ubuntu y Debian | sudo apt-get install unixodbc libgssapi-krb5-2 |
| Red Hat y Fedora | sudo dnf install unixODBC krb5-libs |
| Alpino | apk add unixodbc gcompat |
Luego instala msodbcsql18 desde el repositorio de paquetes de Microsoft. Para repositorios y versiones de paquetes específicos de distribución, consulte la guía de instalación de controladores ODBC.
Las compilaciones de imágenes Docker tienen éxito, pero las conexiones fallan en tiempo de ejecución
Síntomas:
La imagen se construye y PHP arranca, pero PDO::__construct() arroja un error de controlador ODBC no encontrado.
Corrección:
Verifica que el controlador ODBC esté instalado en la imagen de tiempo de ejecución, no solo en la fase de compilación. Instala msodbcsql18 y unixodbc-dev en la misma etapa que se implementa en producción. En una construcción de varias etapas, instálalos en la fase final. Una instalación basada en Debian de una sola etapa se ve así:
# 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/*