Información general de los controladores de Microsoft para PHP para SQL Server

Descargar controlador PHP

Los controladores Microsoft para PHP para SQL Server incluyen dos extensiones PHP, SQLSRV y PDO_SQLSRV. PDO_SQLSRV implementa la interfaz PHP Data Objects (PDO). Ambas extensiones utilizan el controlador Microsoft ODBC para SQL Server para conectarse a Microsoft SQL. Sus API de PHP, las opciones específicas del controlador y los tipos de PHP predeterminados difieren. Por ejemplo, SQLSRV devuelve valores de fecha y hora como DateTime objetos por defecto, mientras que PDO_SQLSRV devuelve cadenas por defecto. Para los requisitos del sistema, consulte Requisitos de sistema para los controladores de Microsoft para PHP para SQL Server.

Elige SQLSRV o PDO_SQLSRV

Si... Uso
¿Empiezas un nuevo proyecto sin código PDO en otro sitio? Elige la interfaz que tu aplicación usará de forma consistente. SQLSRV expone funciones procedimentales y descriptores de parámetros explícitos. PDO_SQLSRV encaja en el código organizado en torno a los objetos PDO y PDOStatement.
Ya uso PDO con otra base de datos (MySQL, PostgreSQL, SQLite) PDO_SQLSRV, así que tu capa de acceso a datos se mantiene consistente entre bases de datos.
Utiliza un framework o librería que espere un objeto de conexión PDO PDO_SQLSRV.
Se necesita control manual, bloque a bloque, sobre cuándo se envían los datos del flujo SQLSRV, usando sqlsrv_send_stream_data(). PDO_SQLSRV también transmite valores grandes, vinculando un recurso de flujo de PHP con PDO::PARAM_LOB, pero envía todo el flujo automáticamente durante execute() en lugar de en bloques controlados por el llamador.
Mantener una aplicación que ya llama a funciones sqlsrv_* SQLSRV, a menos que planees reescribir su código de acceso a datos para PDO.

Instala una de las extensiones o ambas. Las descargas de Windows contienen binarios de extensión separados; en Linux y macOS, instala por separado los paquetes sqlsrv y pdo_sqlsrv. Puedes cargar ambos en el mismo proceso PHP. SQLSRV devuelve recursos de conexión y recursos de instrucción; PDO_SQLSRV devuelve objetos PDO y PDOStatement. No pases un recurso de una API a otra.

Usar PDO no hace que la sintaxis de Transact-SQL (T-SQL) sea portátil a otra base de datos. PDO te ofrece una interfaz común en PHP; tus consultas, esquema, autenticación y atributos específicos del controlador pueden seguir dependiendo de Microsoft SQL. Del mismo modo, usar la extensión procedimental no requiere organización procedimental en toda tu aplicación: puedes llamar a SQLSRV desde tus propias clases.

Compara el mismo resultado en ambas APIs

Ejecuta estos programas antes de elegir la representación PHP que espera tu aplicación. Se seleccionan el mismo entero, fecha y SQL NULL, pero los valores por defecto no son idénticos. No se requieren tablas ni bases de datos de ejemplo.

Instala y carga la extensión seleccionada. Establece SQL_SERVER, SQL_DATABASE, SQL_USER, y SQL_PASSWORD en el entorno de procesos para una base de datos de prueba de SQL Server existente. El certificado del servidor debe ser confiable y coincidir con el punto final configurado. Para la configuración y las alternativas de Azure sin contraseña, consulta Conectarse al servidor.

SQLSRV

Guarda este programa completo como compare-sqlsrv.php, y ejecuta php compare-sqlsrv.php.

<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $value = getenv($name);
    if ($value === false || $value === '') {
        throw new RuntimeException("Set $name before running this example.");
    }
    $config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$conn = sqlsrv_connect($config['SQL_SERVER'], [
    'Database' => $config['SQL_DATABASE'],
    'UID' => $config['SQL_USER'],
    'PWD' => $config['SQL_PASSWORD'],
    'Encrypt' => true,
    'TrustServerCertificate' => false,
    'LoginTimeout' => 30,
    'CharacterSet' => 'UTF-8',
]);
if ($conn === false) {
    throw new RuntimeException(print_r(sqlsrv_errors(), true));
}
$stmt = null;
try {
    $stmt = sqlsrv_query($conn, "SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    if ($stmt === false) {
        throw new RuntimeException(print_r(sqlsrv_errors(), true));
    }
    $row = sqlsrv_fetch_array($stmt, SQLSRV_FETCH_ASSOC);
    if ($row === false) {
        throw new RuntimeException(print_r(sqlsrv_errors(), true));
    }
    if (!is_array($row) || $row['CountValue'] !== 42
        || !($row['DayValue'] instanceof DateTime)
        || $row['DayValue']->format('Y-m-d') !== '2026-10-19'
        || $row['Missing'] !== null) {
        throw new RuntimeException('Unexpected SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

Resultado esperado:

int, DateTime, null

PDO_SQLSRV

Guarda este programa separado como compare-pdo.php, y ejecuta php compare-pdo.php. Deliberadamente deja la obtención de valores numéricos y fechas en los valores predeterminados de PDO_SQLSRV.

<?php
$config = [];
foreach (['SQL_SERVER', 'SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $value = getenv($name);
    if ($value === false || $value === '') {
        throw new RuntimeException("Set $name before running this example.");
    }
    $config[$name] = $value;
}
foreach (['SQL_DATABASE', 'SQL_USER', 'SQL_PASSWORD'] as $name) {
    $config[$name] = '{' . str_replace('}', '}}', $config[$name]) . '}';
}
$server = $config['SQL_SERVER'];
$database = $config['SQL_DATABASE'];
$pdo = new PDO(
    "sqlsrv:Server=$server;Database=$database;Encrypt=true;"
    . "TrustServerCertificate=false;LoginTimeout=30",
    $config['SQL_USER'],
    $config['SQL_PASSWORD'],
    [
        PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
        PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
    ]
);
$stmt = null;
try {
    $stmt = $pdo->query("SELECT CAST(42 AS int) AS CountValue, "
        . "CAST('2026-10-19' AS date) AS DayValue, CAST(NULL AS int) AS Missing");
    $row = $stmt->fetch(PDO::FETCH_ASSOC);
    if ($row !== ['CountValue' => '42', 'DayValue' => '2026-10-19', 'Missing' => null]) {
        throw new RuntimeException('Unexpected PDO_SQLSRV values or default types.');
    }
    echo get_debug_type($row['CountValue']), ', ',
        get_debug_type($row['DayValue']), ', ', get_debug_type($row['Missing']), PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

Resultado esperado:

string, string, null

Ambos programas solicitan explícitamente claves de resultado con nombre. Estos arreglos PHP utilizan nombres de columnas como CountValue, en lugar de índices numéricos basados en ceros. Un SQL NULL se convierte en PHP null en cualquiera de las dos APIs. No es la cadena vacía ni una fila de resultados que falta.

Ambos programas leen el nombre real de la base de datos, el nombre de usuario y la contraseña a partir de las variables de entorno. Se aplican caracteres de escape a estos valores una vez para el manejo de conexiones al estilo ODBC del controlador PHP. Duplicar las llaves de cierre e incluir el valor entre llaves preserva los caracteres especiales; no renombra la base de datos ni cambia la contraseña almacenada. Para más información, consulta Conexión al servidor.

Los ejemplos se detienen al producirse errores y liberan recursos en finally. SQLSRV informa fallos de bases de datos a través de false y sqlsrv_errors(); PDO_SQLSRV lanza excepciones por fallos de conexión y utiliza excepciones para fallos de consulta con el modo de error configurado. En una aplicación web, detecta estas excepciones en el código que gestiona la solicitud. Registra los datos de diagnóstico en registros protegidos en lugar de devolverlos a un navegador.

Después del ejercicio, elimina compare-sqlsrv.php y compare-pdo.php si ya no los necesitas. Borra las variables del entorno de credenciales del proceso de prueba cuando termines.

Elige tipos, codificación y manejo de errores

Decide qué tipos de PHP espera tu aplicación, cómo gestiona el texto y los errores, y cuándo libera recursos de la base de datos.

Decisión SQLSRV PDO_SQLSRV Efecto en el código de aplicación
Tipos de resultados enteros Enteros PHP nativos para columnas de SQL int. Cadenas por defecto; las solicitudes PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE admiten tipos numéricos de PHP. Las comparaciones estrictas y la salida serializada pueden variar. No asumas que todos los tipos numéricos SQL encajan en un entero o float en PHP.
Resultados de fecha y hora DateTime objetos por defecto; ReturnDatesAsStrings selecciona cadenas. Cadenas por defecto; PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE selecciona objetos. Normaliza la representación antes de serializarla o pasarla al código de la aplicación.
Codificación de caracteres Establezca CharacterSet => 'UTF-8' explícitamente. UTF-8 es el valor predeterminado; configúralo con PDO::SQLSRV_ATTR_ENCODING. No transfieras la opción SQLSRV dentro de una cadena DSN de PDO.
Gestión de errores Revisa false y captura inmediatamente la colección completa de errores SQLSRV. Configurar PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION. Una fila faltante y una consulta fallida requieren un manejo diferente.
Reutilización de parámetros Vincula variables por referencia en los descriptores sqlsrv_prepare(). Use bindParam() para una variable o bindValue() para su valor actual. Reasignar la variable afecta a una vinculación de referencia, no a una vinculación a un valor previo.
Cleanup Libere las sentencias, luego cierre el recurso de la conexión. Referencias a la instrucción de liberación, luego al objeto PDO. Una instrucción puede mantener viva una conexión PDO después de que otra referencia se establezca en null.

Si migras una aplicación existente, prueba estos comportamientos con valores representativos antes de cambiar su código de base de datos. Incluye texto no ASCII, SQL NULL, fechas, valores decimales exactos y parámetros de salida de procedimientos almacenados. También compara cómo tu framework configura los atributos PDO. Reemplazar solo nombres de funciones no migra el manejo de errores, la asignación de referencias ni los tipos PHP devueltos.

Para un flujo de trabajo de ejemplo de escritura y lectura con ambas APIs, utiliza la guía de programación. Para ejecuciones repetidas y entradas tipadas, utiliza Comparar funciones de ejecución de consultas.

Conoce para qué sirve cada componente

Tu elección de extensión cambia la API de PHP y sus conversiones de tipos. Ambas extensiones utilizan ODBC para comunicarse con el servidor, cifrar conexiones y autenticarse. El sistema operativo suministra certificados de confianza y servicios como autenticación de Windows o Kerberos. El destino SQL controla permisos, esquema y sentencias T-SQL compatibles.

Los programas de comparación utilizan autenticación SQL para SQL Server. Para Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics, SQL database en Fabric o Warehouse en Fabric, configura el endpoint de servicio y la autenticación soportada antes de reutilizar el patrón de fetch. Ambos productos Fabric requieren autenticación de Microsoft Entra ID; Warehouse también requiere desactivar múltiples conjuntos activos de resultados (MARS). Una comparación entre tipos correcta en SQL Server no establece que un destino diferente admita todas las características mencionadas en esta introducción general.

Qué ofrecen ambas extensiones

  • Autenticación integrada, autenticación SQL y autenticación Microsoft Entra ID, dependiendo del soporte del destino. La identidad gestionada no usa una contraseña de aplicación; ActiveDirectoryServicePrincipal usa un ID de cliente y un secreto de cliente. Para más información, consulta Conexión al servidor.
  • Consultas parametrizadas, sentencias preparadas y parámetros direccionales (entrada/salida). Para más información, véase Comparando funciones de ejecución y Utilizando parámetros direccionales.
  • Transacciones, parámetros de entrada de flujo para valores grandes de caracteres y binarios, y parámetros de tipo tabla.
  • Always Encrypted, incluyendo enclaves seguros donde el controlador ODBC y el destino SQL Server los soportan. Para más información, consulte Uso de Always Encrypted con los controladores de Microsoft para PHP para SQL Server.
  • Conexiones a SQL Server, Azure SQL Database, Azure SQL Managed Instance, Azure Synapse Analytics, base de datos SQL en Microsoft Fabric y Warehouse en Microsoft Fabric. Las características de autenticación y SQL varían según el destino; véase conexiones Azure y Fabric.