Conexión al servidor

Descargar controlador PHP

Utiliza esta guía para abrir una conexión, verificar los valores que recibe PHP y liberar la conexión cuando termine el trabajo. Los programas utilizan autenticación SQL Server para una base de datos de prueba local o remota de SQL Server. Para conexiones sin contraseña de Azure y Fabric, utiliza Connect to Azure SQL y Fabric SQL.

SQLSRV acepta un nombre de servidor y un array asociativo de opciones de conexión. PDO_SQLSRV implementa PHP Data Objects (PDO) y acepta una cadena de nombre de fuente de datos (DSN), argumentos de credenciales separados y una matriz de atributos PDO. Ambos utilizan el controlador Microsoft ODBC para SQL Server. Una conexión que funciona con una API no hace que los nombres de opciones o los tipos de PHP de la otra API sean intercambiables.

Antes de conectar

  1. Instala un entorno PHP compatible y un controlador Microsoft ODBC, y carga la extensión PHP que planeas usar.
  2. Revisa el proceso PHP que ejecuta tu aplicación. Ejecuta php --ini para encontrar la configuración de línea de comandos y php -m listar sus extensiones cargadas. SQLSRV requiere sqlsrv. PDO_SQLSRV requiere PDO y pdo_sqlsrv. Un servidor web puede utilizar un php.ini, un Integration Runtime y una cuenta diferentes a los de tu terminal.
  3. Obtén la dirección del servidor, el nombre de la base de datos y una identidad con permiso para conectarte. Un inicio de sesión en la base de datos no concede automáticamente permiso a todas las tablas.
  4. Configura el acceso a la red y un certificado de servidor confiable. Estos programas solicitan cifrado y validación de certificados explícitamente. Conéctate mediante el nombre de host que figura en el certificado, en lugar de sustituir una dirección IP que no esté cubierta por el certificado.

Establece estas variables en el entorno del proceso PHP, usando tu shell, herramienta de desarrollo o configuración de hosting. No comitas un archivo de contraseñas ni imprimas el entorno.

Variable Value
SQL_SERVER El nombre del host del servidor, opcionalmente precedido por tcp: y seguido de ,<port>.
SQL_DATABASE Una base de datos existente a la que tu inicio de sesión pueda acceder.
SQL_USER Inicio de sesión de SQL Server.
SQL_PASSWORD La contraseña de ese inicio de sesión, proporcionada mediante configuración protegida.

Lee la configuración del servidor y la base de datos desde la configuración de la aplicación de confianza, no los parámetros de las solicitudes web. El ejemplo del PDO sitúa esas configuraciones en un DSN. Mantenga las palabras clave de conexión bajo el control de la aplicación.

Almacena el nombre real de la base de datos, el nombre de usuario y la contraseña en las variables de entorno, sin añadir ni duplicar llaves por tu cuenta. Ambas extensiones PHP requieren escape al estilo ODBC incluso para opciones de array SQLSRV y argumentos de constructores PDO: duplica cada llave de cierre y encierra el valor entre llaves. Cada programa hace esto una vez antes de pasar estos valores al controlador. Las llaves externas conservan las llaves literales al principio y al final de un valor y evitan que los puntos y coma dentro del nombre de la base de datos separen los ajustes del PDO DSN. Este escape es independiente de la vinculación de parámetros de Transact-SQL (T-SQL).

Abrir, consultar y cerrar con SQLSRV

Guarda este programa como connect-sqlsrv.php, y ejecuta php connect-sqlsrv.php. Ejecuta una consulta T-SQL sin crear tablas ni cambiar datos. CharacterSet selecciona UTF-8 para los datos de caracteres; no cambia los tipos de columna ni la colación de la base de datos.

<?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 {
    $sql = "SELECT CAST(42 AS int) AS Value, N'caf' + NCHAR(233) AS Label, "
        . "CAST(NULL AS int) AS Missing";
    $stmt = sqlsrv_query($conn, $sql, [], ['QueryTimeout' => 30]);
    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 ($row !== ['Value' => 42, 'Label' => "caf\u{00e9}", 'Missing' => null]) {
        throw new RuntimeException('Unexpected SQLSRV values or PHP types.');
    }
    echo json_encode($row, JSON_THROW_ON_ERROR), PHP_EOL;
} finally {
    if (is_resource($stmt)) {
        sqlsrv_free_stmt($stmt);
    }
    sqlsrv_close($conn);
}

Resultado esperado:

{"Value":42,"Label":"caf\u00e9","Missing":null}

La conexión y la instrucción son recursos de PHP, identificadores que se pasan a las sqlsrv_* funciones. Comprueba si existe false antes de utilizar cualquiera de los identificadores. Recupera sqlsrv_errors() inmediatamente después de un error, ya que una llamada posterior a SQLSRV puede sobrescribir la colección de errores.

SQLSRV_FETCH_ASSOC devuelve un array asociativo con nombres de columnas como claves. SQLSRV_FETCH_NUMERIC devuelve claves numéricas basadas en cero; el predeterminado SQLSRV_FETCH_BOTH incluye ambas formas. Para sqlsrv_fetch_array(), null significa que no hay más filas y false significa un error. Un SQL NULL dentro de una fila es PHP null; no significa que falte la fila. Utiliza === para distinguir estos valores.

Abrir, consultar y cerrar con PDO_SQLSRV

Guarda este programa separado como connect-pdo.php, y ejecuta php connect-pdo.php con el mismo entorno. sqlsrv: elige PDO_SQLSRV, no el controlador genérico PDO_ODBC de 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]) . '}';
}
$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::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
        PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8,
    ]
);

$stmt = null;
try {
    $sql = "SELECT CAST(42 AS int) AS Value, N'caf' + NCHAR(233) AS Label, "
        . "CAST(NULL AS int) AS Missing";
    $stmt = $pdo->prepare($sql, [PDO::SQLSRV_ATTR_QUERY_TIMEOUT => 30]);
    $stmt->execute();
    $row = $stmt->fetch();
    if ($row !== ['Value' => '42', 'Label' => "caf\u{00e9}", 'Missing' => null]) {
        throw new RuntimeException('Unexpected PDO_SQLSRV values or PHP types.');
    }
    echo json_encode($row, JSON_THROW_ON_ERROR), PHP_EOL;
} finally {
    $stmt = null;
    $pdo = null;
}

Resultado esperado:

{"Value":"42","Label":"caf\u00e9","Missing":null}

PDO_SQLSRV devuelve esta columna int como una cadena PHP por defecto. Para solicitar tipos numéricos PHP para columnas numéricas soportadas, se fija PDO::SQLSRV_ATTR_FETCHES_NUMERIC_TYPE en true. No uses una conversión de tipo de PHP indiscriminadamente para valores decimales; una conversión en coma flotante puede perder precisión.

Los atributos PDO son configuraciones en el objeto de conexión o de la sentencia. PDO::ATTR_ERRMODE con PDO::ERRMODE_EXCEPTION hace que los fallos de operación de la base de datos generen PDOException. La creación de la conexión lanza una excepción en caso de fallo, independientemente de esa configuración. PDO::FETCH_ASSOC da claves nombradas, PDO::FETCH_NUM da claves numéricas basadas en cero y PDO::FETCH_BOTH da ambas. fetch() devuelve false al final del resultado; los valores SQL NULL dentro de una fila siguen siendo PHP null.

Estos programas de línea de comandos permiten que los fallos detengan la ejecución. En una aplicación web, captura las excepciones en el código que administra la solicitud. Registrar los detalles de diagnóstico en registros protegidos y devolver una respuesta de error genérica. No envíes sqlsrv_errors()rastros de excepciones, cadenas de conexión ni tokens a un navegador.

Elección de un modo de autenticación

Mode Usado para Vea
Autenticación de SQL Server SQL Server local, contenedores y Azure SQL cuando Microsoft Entra ID no está disponible Conéctate usando autenticación SQL Server
Autenticación integrada (sin nombre de usuario ni contraseña en la configuración de conexión) Identidades de Windows o clientes de Linux/macOS configurados para Kerberos Conéctate usando autenticación de Windows
Microsoft Entra ID (Authentication o la palabra clave AccessToken) Destinos de Azure SQL y Fabric SQL configurados para Microsoft Entra ID Conéctate usando la autenticación de Microsoft Entra

Para la autenticación SQL, SQLSRV toma UID y PWD en su array de opciones de conexión. PDO_SQLSRV toma el nombre de usuario y la contraseña como segundo y tercer argumento para new PDO(), no como palabras clave DSN. Para un token de acceso, SQLSRV recibe AccessToken en el array de opciones, mientras que PDO_SQLSRV lo toma en el DSN.

Si omites el nombre de usuario, la contraseña, Authentication, y AccessToken, ambos controladores solicitan autenticación integrada a ODBC usando Trusted_Connection=Yes. En Linux y macOS, esta solicitud requiere un ticket válido de Kerberos y una configuración de autenticación integrada ODBC. No concede acceso a un servidor remoto a una cuenta local arbitraria.

Configura la conexión y sus instrucciones

La configuración de conexión se aplica a la sesión que abres. La configuración de las instrucciones se aplica a una consulta concreta. Establece tiempos de espera y tipos de resultado explícitamente cuando tu aplicación necesite valores distintos a los valores por defecto.

Purpose SQLSRV PDO_SQLSRV Responsable del comportamiento
Punto de conexión y base de datos Argumento del servidor y opción Database. Server y Database palabras clave DSN. ODBC y el destino SQL.
Credenciales de SQL Opciones UID y PWD. Argumentos de nombre de usuario y contraseña del constructor. Gestión de credenciales de extensión y autenticación de servidores.
autenticación de Microsoft Entra Authentication opción, o la opción separada AccessToken. Authentication o AccessToken palabra clave DSN, con credenciales omitidas para un token externo. autenticación ODBC; la aplicación adquiere tokens externos.
Encryption Encrypt => true. Encrypt=true en la DSN. Seguridad de transporte ODBC.
Validación de certificados TrustServerCertificate => false. TrustServerCertificate=false en la DSN. ODBC y la configuración de confianza de certificados del sistema operativo.
Tiempo de espera para el establecimiento de la conexión Opción de conexión LoginTimeout, en segundos. LoginTimeout Palabra clave DSN, en segundos. ODBC. No es el tiempo de espera para la ejecución de la instrucción.
Tiempo de espera de consulta Opción de instrucción QueryTimeout, en segundos. PDO::SQLSRV_ATTR_QUERY_TIMEOUT, en la conexión o en la instrucción. Manejo de instrucciones de extensión y ODBC.
Codificación de caracteres CharacterSet => 'UTF-8' Opción de conexión. PDO::SQLSRV_ATTR_ENCODING => PDO::SQLSRV_ENCODING_UTF8. Conversión de extensión PHP. PDO_SQLSRV por defecto es UTF-8; SQLSRV se ajusta por defecto a la codificación del sistema.
Objetos de fecha y hora ReturnDatesAsStrings es false por defecto, por lo que las columnas de fecha y hora devuelven DateTime objetos. Cadenas de caracteres por defecto; utiliza PDO::SQLSRV_ATTR_FETCHES_DATETIME_TYPE para solicitar objetos. Conversión de tipos de extensión PHP.
Conjuntos de resultados activos múltiples (MARS) MultipleActiveResultSets Opción de conexión. MultipleActiveResultSets Palabra clave DSN. Compatibilidad con ODBC y el destino. Ambas extensiones lo habilitan por defecto; desactívalo para Warehouse en Fabric.
Recuperación por inactividad Opciones de conexión ConnectRetryCount y ConnectRetryInterval. Las mismas palabras clave de DSN. ODBC. No reintentan operaciones arbitrarias de la aplicación.

Para la lista completa de palabras clave, valores permitidos y valores predeterminados, consulte Opciones de Conexión. No pongas los nombres de constantes CharacterSet, QueryTimeout ni PDO:: en un DSN de PDO.

Administración de la vida útil de la conexión

Abre una conexión cuando una solicitud o trabajo requiera acceso a la base de datos. Reutilízalo durante esa petición o trabajo, y luego libéralo cuando termines. No conectes ni desconectes para cada fila. En un trabajador de larga duración, libera las instrucciones y completa cada transacción antes de aceptar el siguiente trabajo.

SQLSRV cierra las sentencias asociadas cuando cierras su conexión. Las instrucciones de liberación explícita liberan recursos antes de tiempo sin cerrar la conexión. En el caso de PDO, al asignar $pdo = null solo se elimina la referencia a esa variable. A PDOStatement u otra variable puede seguir conservando la conexión. Libera también esas referencias. closeCursor() libera los resultados pendientes para que la instrucción pueda reutilizarse; no es un método de cierre de conexión.

Ambas API se inician en modo de autocommit: una instrucción que se ejecuta correctamente se confirma sin necesidad de una confirmación por parte de la aplicación, a menos que se inicie una transacción. Para un grupo de escrituras que deben tener éxito o fallar juntas, usar sqlsrv_begin_transaction() o $pdo->beginTransaction(), luego hacer commit o revertir explícitamente. Al cerrar una conexión con una transacción pendiente, se intenta una reversión, no una confirmación. No confíes en la limpieza al apagar para implementar tu política de transacciones. Para ver ejemplos completos, consulta Realizar transacciones.

Liberar un handle de conexión PHP no cierra necesariamente su conexión física de red. El pooling ODBC puede conservarlo para su reutilización. El uso de un pool no es motivo para retener recursos de PHP indefinidamente, y PDO_SQLSRV no admite PDO::ATTR_PERSISTENT => true. Para la configuración de agrupación de conexiones específica de la plataforma, véase agrupación de conexiones.

Aplica la guía a tu destino SQL

Los patrones handle, fetch y cleanup se aplican a ambas extensiones en los objetivos SQL soportados. Los puntos finales de conexión, la autenticación, el acceso a la red y las capacidades SQL varían.

Objetivo Adaptación
SQL Server Los programas utilizan un inicio de sesión SQL. La autenticación integrada es otra opción cuando configuras la identidad del proceso PHP.
Azure SQL Database Utiliza el nombre lógico del servidor y la base de datos explícita. Prefiere la autenticación de Microsoft Entra en lugar de las credenciales SQL en estos programas.
Instancia Gestionada de Azure SQL Utiliza el endpoint de la instancia y sus requisitos de acceso a la red. No des por hecho que un endpoint privado es accesible desde tu estación de trabajo.
Azure Synapse Analytics Utiliza el endpoint del pool SQL y comprueba su soporte T-SQL antes de adaptar consultas que creen o modifiquen objetos.
Base de datos SQL en Microsoft Fabric Utiliza los detalles de su conexión a la base de datos y la autenticación Microsoft Entra. No sustituyas el endpoint de analítica SQL.
Almacén en Microsoft Fabric Utiliza su endpoint y base de datos del almacén, autenticación Microsoft Entra, y MultipleActiveResultSets=false.

Para la configuración específica de servicios, véase conexiones de Azure y Fabric.

Solucionar problemas de conexión

Empieza por el paso que falló. Una comprobación exitosa del Protocolo de Control de Transmisión (TCP) no demuestra que la autenticación o la validación del certificado hayan tenido éxito.

Síntoma Check
Call to undefined function sqlsrv_connect() El proceso PHP en ejecución no cargó sqlsrv. Comprueba su php.ini y las advertencias de arranque.
Informes de PDOcould not find driver Confirmar que pdo_sqlsrv está cargado en ese proceso y sqlsrv aparece en PDO::getAvailableDrivers().
No se puede encontrar el controlador ODBC Instala el controlador ODBC de Microsoft y revisa su registro y arquitectura. Instalar una extensión de PHP no instala ODBC.
Tiempo de espera de conexión o servidor no encontrado Comprueba el nombre del servidor, puerto, resolución de nombres, enrutamiento, reglas del firewall y si SQL Server escucha en TCP.
Falla la validación de la cadena de certificados o del nombre de host Instala la cadena de confianza correcta y usa el nombre de host del certificado. No consideres TrustServerCertificate=true una solución para producción.
El inicio de sesión falla o la base de datos no se puede abrir Comprueba el modo de autenticación, nombre de la base de datos, mapeo de inicio de sesión/usuario y permisos. Omitir credenciales solicita autenticación integrada; no selecciona autenticación SQL.
En Terminal funciona pero las solicitudes web fallan Compara el tiempo de ejecución de PHP, las extensiones cargadas, la identidad del proceso, las variables de entorno y el acceso a la red. No expongas una página pública phpinfo() que contenga detalles de configuración.
Una operación posterior falla si el identificador está cerrado Mantén la conexión durante toda la ejecución de las instrucciones. Crea una nueva conexión después de cerrar una; un descriptor antiguo no se vuelve a abrir solo.

Otros artículos de conexión