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.
Los controladores Microsoft para PHP para SQL Server son extensiones de PHP que permiten leer y escribir datos en el Microsoft SQL Motor de base de datos desde scripts PHP. El paquete incluye dos controladores que encapsulan el mismo controlador Microsoft ODBC para SQL Server y comparten las mismas opciones de conexión, así que puedes elegir la API que se adapte a tu base de código:
-
SQLSRV expone una API procedural (
sqlsrv_*funciones) adaptada a las características de SQL Server. - PDO_SQLSRV implementa la interfaz PHP Data Objects (PDO), por lo que el código que ya utiliza PDO para otras bases de datos puede dirigirse a SQL Server con cambios mínimos.
Ambos controladores se conectan a Azure SQL Database, SQL database en Microsoft Fabric, Azure SQL Managed Instance y todas las versiones y ediciones compatibles de SQL Server (incluidas las ediciones Express). Utilizan flujos PHP para mover grandes valores binarios y de caracteres sin cargarlos completamente en memoria.
Elija el punto de partida.
- Para configurar un entorno de desarrollo PHP y ejecutar tu primera consulta, empieza con el Paso 1: Configurar el entorno de desarrollo, luego el Paso 2: Crear una base de datos SQL y el Paso 3: Prueba de concepto conectándose a SQL usando PHP.
- Para instalar el controlador en Linux o macOS, empieza con el tutorial de instalación para Linux y macOS y descarga los controladores de Microsoft para PHP para SQL Server.
- Para conectarte a Azure SQL con autenticación sin contraseña, empieza con Connect usando las opcionesde autenticación y conexión de Microsoft Entra.
- Para hacer que una aplicación existente sea resistente a fallos transitorios, ve a resiliencia de conexión inactiva y Paso 4: Conéctate resilientemente a SQL con PHP.
- Para decidir entre SQLSRV y PDO_SQLSRV, consulta Resumen de los controladores de Microsoft para PHP para SQL Server y Comparando funciones de ejecución.
- Para diagnosticar un problema de instalación, conexión o consulta, ve a Resolución de problemas, Gestión de errores y advertencias, y Actividad de registro.
- Para que una app existente sea más rápida, ve a Ajuste de Rendimiento.
Línea base de producción para Azure SQL
Utiliza este fragmento como punto de partida para una conexión de Azure SQL orientada a la producción con el controlador de PDO_SQLSRV. Lee el servidor y la base de datos a partir de variables de entorno (por ejemplo, la configuración de la app de Azure App Service), se autentica con una identidad gestionada, activa la Seguridad de la Capa de Transporte (TLS) con validación de certificados de servidor, establece un tiempo de espera de inicio de sesión que cubre un conmutamiento por error de arranque en frío y establece ConnectRetryCount y ConnectRetryInterval para la resiliencia de la conexión inactiva de SQL Server. Los auxiliares connectWithRetry y queryWithRetry del nivel de aplicación envuelven tanto la conexión inicial como cada instrucción con un retroceso exponencial limitado, y separan los errores transitorios de conexión (que requieren una nueva conexión) de los errores transitorios de consulta (que reutilizan la misma conexión).
Requiere PHP 8.0 y versiones posteriores, la extensión PDO_SQLSRV y Microsoft controlador ODBC para SQL Server 17.3.1.1 y versiones posteriores para Authentication=ActiveDirectoryMsi. Para consultar la lista completa de valores Authentication admitidos, consulte Conectarse mediante la autenticación de 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 fragmento de código está optimizado para grupos de conmutación por error de Azure SQL Database y Azure SQL Managed Instance.
Driver={ODBC Driver 18 for SQL Server}fija el controlador ODBC 18. Si el host también tiene ODBC 17 instalado, PDO_SQLSRV puede vincularse a ODBC 17. Las versiones antiguas de 17.x rechazan valores másAuthenticationrecientes; por ejemplo,Authentication=ActiveDirectoryMsirequieren ODBC 17.3.1.1 o una versión posterior. Ver Valor inválido especificado para el atributo de cadena de conexión 'Authentication'.ConnectRetryCountyConnectRetryIntervalson palabras clave de la cadena de conexión ODBC que permiten la resiliencia de conexiones inactivas en SQL Server: el controlador vuelve a conectar de forma transparente una conexión inactiva interrumpida. Esto es distinto del nivelqueryWithRetryde aplicación , que intenta de nuevo una sentencia que falla con un error transitorio como un bloqueo o un tiempo de espera de consulta. Los dos son complementarios, así que quédate con ambos. Asegúrate de queLoginTimeoutsea al menosConnectRetryCount * ConnectRetryIntervalpara que la ruta de reconexión por inactividad disponga de todo su margen; el ejemplo usa 90 segundos para cubrir 5 × 15 segundos de reintentos más cierto margen adicional para el inicio de sesión inicial en una conmutación por error en frío.Complemente las llamadas
error_log()a nivel de aplicación con diagnósticos del controlador. Para PDO_SQLSRV, establezcapdo_sqlsrv.log_severityenphp.ini(solo se puede establecer durante la inicialización); para SQLSRV, llame asqlsrv_configure("LogSubsystems", ...)en tiempo de ejecución. Para más información, consulte Actividad 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 = 1Para una identidad gestionada asignada por el usuario, pase el ID de la identidad como argumento
$usernamede PDO (new PDO($dsn, $identityId, null, $options)). Utiliza el ID de cliente de la identidad en Azure App Service o Azure Container Instance; de lo contrario, utiliza su ID de objeto. Los controladores PHP heredan este comportamiento del controlador subyacente de Microsoft ODBC para SQL Server; para más información, consulte Uso de Microsoft Entra ID con el controlador ODBC. PDO_SQLSRV rechazaUIDdentro de la propia DSN, así que usa la ranura del constructor. Pasarnullcomo valor de usuario (como en el ejemplo) selecciona la identidad administrada asignada por el sistema del host de Azure. Para SQLSRV (modo procedimental), pasaUIDen la matriz de opciones de conexión.Establece
MultiSubnetFailover=truecuando te conectes a un agente de escucha de grupo de conmutación por error, a un agente de escucha de grupo de disponibilidad o a un punto de conexión de una instancia de clúster de conmutación por error. Configurarlo mejora el rendimiento de la conexión tanto para los oyentes de grupos de disponibilidad de una sola subred como de múltiples subred. Para más información, consulte Soporte para Alta Disponibilidad, recuperación ante desastres.Para un escalamiento de lectura o un secundario legible, añade
ApplicationIntent=ReadOnlyal Nombre de la Fuente de Datos (DSN).Para nubes soberanas donde el certificado Subject Alternative Name (SAN) no incluye el host al que te conectas, añade
HostNameInCertificateal DSN (por ejemplo,*.database.usgovcloudapi.netpara Azure Government).El controlador se basa en el controlador subyacente de Microsoft ODBC para SQL Server para la adquisición de tokens. Los flujos de identidad administrada, entidad de servicio y token de acceso pasan todos por ODBC. Para obtener más información, vea Uso de Microsoft Entra ID con ODBC Driver.
Para mayor seguridad y portabilidad entre entornos, mantén la información de conexión fuera de tu código. Guarda la información de conexión en el sistema de configuración de tu aplicación y utiliza Azure Key Vault para valores sensibles y ajustes de conexión gestionados centralmente.
La conexión SQLSRV equivalente utiliza
sqlsrv_connect($server, ['Database' => $database, 'Encrypt' => true, 'Authentication' => 'ActiveDirectoryMsi', /* ... */])y devuelve un recurso. El patrón de reintento es el mismo: capturar un valor de retornofalsedesqlsrv_connect, inspeccionarsqlsrv_errors()para comprobar el SQLSTATE y esperar un tiempo antes de reintentar. Para un ejemplo resuelto, véase el Paso 4: Conectarse resilientemente a SQL con PHP.Las funciones auxiliares de reintento leen
$e->errorInfo[1], protegido porisset().PDOException::$errorInfose declara como?arrayy tiene como valor predeterminadonull, por lo que la comprobación defensiva recurre a un código de controlador de0y deja que el prefijo SQLSTATE08determine si se debe reintentar.
Para obtener más información sobre cada parte de esta configuración, consulte:
- Opciones de conexión
- Conéctate usando la autenticación de Microsoft Entra
- Resiliencia de la conexión en reposo
- Conexión a Microsoft Azure SQL Database
- Soporte para Alta Disponibilidad, recuperación ante desastres
Para consultar el catálogo de errores transitorios de Azure SQL, consulte Solucionar errores transitorios de conexión.
Características clave
- Dos API, un paquete de controladores: SQLSRV procedimental para código centrado en SQL Server, o PDO_SQLSRV para código PDO portable.
- Soporte para plataformas amplias: Funciona en Windows, Linux y macOS con versiones compatibles con PHP.
-
Conexiones cifradas: Conexiones cifradas TLS mediante
Encrypt=true, con la validación del certificado del servidor controlada porTrustServerCertificate. - Autenticación Microsoft Entra ID: Las conexiones sin contraseña con identidad gestionada, principal de servicio y token de acceso fluyen a través del controlador Microsoft ODBC subyacente para SQL Server.
- Always Encrypted: cifrado del lado cliente para columnas confidenciales, con enclaves seguros opcionales para operaciones en contexto.
-
Resiliencia de conexión: La conexión inactiva incorporada se reintenta con
ConnectRetryCountyConnectRetryInterval. - Flujos PHP: Leen y escriben grandes valores binarios y de caracteres como flujos en lugar de cargarlos en memoria.
-
Soporte para tipos de datos de Rich SQL Server: datetimeoffset, parámetros de valoración en tabla, nvarchar y Unicode con
PDO::SQLSRV_ENCODING_UTF8.
Primeros pasos
| Artículo | Descripción |
|---|---|
| Requisitos del sistema | Compatibles con PHP, sistemas operativos y versiones de SQL Server. |
| Matriz de compatibilidad | Matriz detallada de compatibilidad para las versiones de controladores PHP. |
| Descarga los controladores de Microsoft para PHP para SQL Server | Enlaces de descarga y libera artefactos. |
| Tutorial de instalación para Linux y macOS | Instala el controlador y sus requisitos previos de ODBC en Linux y macOS. |
| Carga de los drivers | Activa las extensiones en php.ini. |
| Empezando con el controlador SQL de PHP | Guía de principio a fin que une los cuatro pasos de inicio. |
| Visión general del controlador SQL PHP | ¿Qué contiene el paquete y cuándo elegir SQLSRV o PDO_SQLSRV. |
Configuración y conexión
| Artículo | Descripción |
|---|---|
| Conexión al servidor | Abre una conexión a una instancia de SQL Server desde PHP. |
| Opciones de conexión | Referencia completa para palabras clave de conexión, valores predeterminados y cómo configurarlos. |
| Conexión a Microsoft Azure SQL Database | Conecta una aplicación PHP a Azure SQL Database. |
| Conéctate en un puerto especificado | Apunta a un puerto TCP no predeterminado. |
| Agrupación de conexiones | Reutiliza conexiones ODBC entre peticiones PHP. |
| Desactivar múltiples conjuntos activos de resultados (MARS) | Desactiva MARS para compatibilidad. |
| Compatibilidad con LocalDB | Conéctate a una instancia de SQL Server LocalDB. |
| Soporte para Alta Disponibilidad, recuperación ante desastres | Escuchas de grupos de disponibilidad y conmutación por error entre varias subredes. |
| Resiliencia de la conexión en reposo | Reconexión automática de conexiones inactivas interrumpidas. |
Authenticate
| Artículo | Descripción |
|---|---|
| Conéctate usando la autenticación de Microsoft Entra | Identidad administrada, entidad de servicio, token de acceso y flujos de autenticación mediante contraseña. |
| Conéctate usando autenticación SQL Server | Usa un inicio de sesión SQL con nombre de usuario y contraseña. |
| Conéctate usando autenticación de Windows | Utiliza la autenticación integrada de Windows en equipos unidos a un dominio. |
Secure
| Artículo | Descripción |
|---|---|
| Consideraciones de seguridad | Modelo de amenazas y orientación en profundidad de defensa para aplicaciones PHP. |
| Siempre cifrado con los controladores PHP | Configure el cifrado del lado cliente para columnas confidenciales. |
| Always Encrypted con enclaves seguros | Permitir operaciones avanzadas en columnas cifradas con enclaves seguros. |
Recuperar y actualizar datos
| Artículo | Descripción |
|---|---|
| Guía de programación | Guía de programación de extremo a extremo para ambos controladores. |
| Comparando funciones de ejecución | Elige la función de ejecución adecuada para tu carga de trabajo. |
| Ejecución directa y preparada de sentencias (PDO_SQLSRV) | Cuándo usar ejecución directa frente a declaraciones preparadas. |
| Recuperación de datos | Busca filas, columnas y valores de streaming. |
| Actualización de datos | Inserta, actualiza y elimina filas. |
| Realizar consultas parametrizadas | Vincula parámetros para protegerte contra la inyección SQL. |
| Enviar datos como flujo | Transmite valores binarios y de caracteres grandes a SQL Server. |
| Ejecutar transacciones | Agrupar estados en transacciones atómicas. |
| Utiliza parámetros con valores de tabla | Pasa un TABLE parámetro a un procedimiento almacenado. |
| Especifica un tipo de cursor y selecciona filas | Elige cursores solo hacia adelante, estáticos, dinámicos o de conjunto de teclas. |
Tipos de datos
| Artículo | Descripción |
|---|---|
| Conversión de tipos de datos | Cómo el controlador asigna los tipos PHP a los tipos de SQL Server. |
| Tipos de datos predeterminados de SQL Server | Tipo de SQL Server por defecto para cada valor PHP. |
| Tipos de datos PHP por defecto | Tipo de PHP predeterminado para cada tipo de columna de SQL Server. |
| Especificar tipos de datos de SQL Server (SQLSRV) | Anula el tipo de SQL Server al vincular parámetros. |
| Especificar tipos de datos PHP | Sobrescribe el tipo de PHP al obtenerlo. |
| Enviar y recuperar datos UTF-8 | Utilice PDO::SQLSRV_ENCODING_UTF8 para conversiones de ida y vuelta en Unicode. |
| Enviar y recuperar datos ASCII en Linux y macOS | Gestiona las conversiones de ida y vuelta de ASCII en equipos que no ejecutan Windows. |
| Formatear decimales y dinero (SQLSRV) | Formatea las columnas decimales y de dinero con el controlador SQLSRV. |
| Dar formato a decimales y valores monetarios (PDO_SQLSRV) | Dé formato a las columnas decimal y money con el controlador PDO_SQLSRV. |
| Configuración regional no perteneciente al sistema | Separadores decimales localizados y otras consideraciones locales. |
Errores y diagnósticos
| Artículo | Descripción |
|---|---|
| Errores de manejo y advertencias | Gestión de errores y advertencias con ambos controladores. |
| Configurar la gestión de errores y advertencias (SQLSRV) | Ajusta cómo el controlador SQLSRV informa de errores y advertencias. |
| Gestionar errores y advertencias (SQLSRV) | Inspecciona los errores devueltos por las funciones SQLSRV. |
| Actividad de registro | Active el registro del controlador para la captura de diagnósticos. |
Despliegue y operación
| Artículo | Descripción |
|---|---|
| Ajuste del rendimiento | Gestión de conexiones, agrupación, sentencias preparadas, cursores, memoria y monitorización en el lado del servidor. |
| Solución de problemas | Diagnostica problemas comunes de instalación, conexión, consulta, tipo de datos, transacción y contenedor. |
Contenido de referencia
| Artículo | Descripción |
|---|---|
| Referencia de la API de controladores SQLSRV | Todas las sqlsrv_* funciones, parámetros y valores de retorno. |
| Referencia del controlador PDO_SQLSRV | Métodos PDO y PDOStatement soportados por el controlador PDO_SQLSRV. |
| Constantes | Constantes expuestas por los controladores, incluyendo constantes de tipo y codificación. |
Tareas relacionadas
| Artículo | Descripción |
|---|---|
| Notas de lanzamiento | Historial de versiones por versión con nuevas funciones, correcciones de errores, cambios de soporte en la plataforma y enlaces de descarga. |
| Sobre ejemplos de código en la documentación | Convenciones utilizadas por los ejemplos de código de esta sección. |
| Ejemplos de código para el controlador SQL PHP | Ejemplos de aplicaciones de extremo a extremo para SQLSRV y PDO_SQLSRV. |
| Recursos de soporte técnico | Comunidad y canales de apoyo. |