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.
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
- Instala un entorno PHP compatible y un controlador Microsoft ODBC, y carga la extensión PHP que planeas usar.
- Revisa el proceso PHP que ejecuta tu aplicación. Ejecuta
php --inipara encontrar la configuración de línea de comandos yphp -mlistar sus extensiones cargadas. SQLSRV requieresqlsrv. PDO_SQLSRV requierePDOypdo_sqlsrv. Un servidor web puede usar un tiempo de ejecución y una cuenta diferentesphp.inia los de tu terminal. - 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.
- 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 por el nombre de host en el certificado en lugar de sustituir el nombre de host por una dirección IP que el certificado no cubre.
Establece estas variables en el entorno del proceso PHP, usando tu shell, herramienta de desarrollo o configuración de hosting. No confirmes un archivo de contraseña ni muestres las variables de 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 |
Una cuenta 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.
Guarda el nombre real de la base de datos, nombre de usuario y contraseña en las variables de entorno, sin añadir ni duplicar llaves tú mismo. 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 columnas ni la intercalació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 sentencia son recursos PHP, identificadores que pasas a sqlsrv_* funciones. Comprueba si hay false antes de usar cualquiera de las dos asas. Recupérelo sqlsrv_errors() inmediatamente después de un fallo porque una llamada SQLSRV posterior puede reemplazar 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. Use === al 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 construcción de la conexión lanza una excepción si falla, 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 permanecen en 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 gestiona 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 otorga acceso a un servidor remoto a una cuenta local arbitraria.
Configurar la conexión y sus instrucciones
La configuración de conexión se aplica a la sesión que abres. La configuración de 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 |
|---|---|---|---|
| Endpoint y base de datos | Argumento sobre el servidor y Database la opción. |
Server y Database palabras clave DSN. |
ODBC y el objetivo SQL. |
| Credenciales de SQL |
UID y PWD opciones. |
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 conexión |
LoginTimeout Opción de conexión, en segundos. |
LoginTimeout Palabra clave DSN, en segundos. |
ODBC. No es el tiempo de ejecución de la sentencia. |
| Tiempo de espera de consulta |
QueryTimeout Opción de instrucción, en segundos. |
PDO::SQLSRV_ATTR_QUERY_TIMEOUT, sobre la conexión o instrucción. |
Gestión de extensión e instrucciones 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 por defecto; se usa 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. |
ODBC y soporte de destino. Ambas extensiones lo habilitan por defecto; deshabilítelo para Warehouse en Fabric. |
| Recuperación en inactividad | Opciones de conexión ConnectRetryCount y ConnectRetryInterval. |
Las mismas palabras clave de DSN. | ODBC. No vuelven a intentar 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.
Gestionar la duración 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 declaraciones y completa cada transacción antes de aceptar el siguiente trabajo.
SQLSRV cierra las sentencias asociadas cuando cierras su conexión. Liberar explícitamente las sentencias antes libera recursos sin cerrar la conexión. Para PDO, asignar $pdo = null solo elimina la referencia de esa variable. A PDOStatement u otra variable puede seguir conservando la conexión. Publica 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 APIs comienzan en modo autocommit: una declaración exitosa se compromete sin un commit de aplicación separado a menos que inicies 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 revertirla, no hacer un commit. No confíes en la limpieza al apagar para implementar tu política de transacciones. Para 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 pooling no es motivo para conservar recursos PHP indefinidamente, y PDO_SQLSRV no lo soporta 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 de 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. Prefiero la autenticación 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 PDO could 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 con un identificador cerrado | Mantén la conexión durante todo el proceso de declaración. 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
- Conéctate en un puerto especificado
- Opciones de conexión
- Agrupación de conexiones
- Desactivar múltiples conjuntos activos de resultados (MARS)
- Compatibilidad con LocalDB
- Soporte para alta disponibilidad y recuperación ante desastres
- Conexión a Microsoft Azure SQL Database
- Resiliencia de la conexión en reposo