W3docs

Guía completa sobre la función mysqli_thread_safe en PHP

Aprende qué significa la seguridad de hilos en PHP, por qué mysqli_thread_safe no existe y cómo verificar si tu compilación es ZTS o NTS.

Al trabajar con bases de datos MySQL en PHP mediante la extensión mysqli, una pregunta frecuente es: "¿Es mysqli seguro para hilos y existe una función mysqli_thread_safe() que pueda llamar para verificarlo?"

La respuesta corta es que mysqli_thread_safe() no es una función en PHP, y la seguridad de hilos no es algo que se consulte en tiempo de ejecución. Es una propiedad de cómo se compiló tu binario de PHP. Esta guía explica qué significa realmente "thread-safe" en PHP, por qué la seguridad de hilos en mysqli es una decisión en tiempo de compilación, cuándo importa en la práctica y cómo verificarlo en tu entorno.

Qué significa "Thread-Safe" en PHP

Un programa es thread-safe cuando múltiples hilos pueden ejecutar el mismo código al mismo tiempo sin corromper datos compartidos. En una compilación thread-safe, el motor PHP protege el estado global interno (la tabla de símbolos, el gestor de memoria, los globals de extensiones, etc.) de modo que dos hilos ejecutándose dentro del mismo proceso no puedan sobrescribir los datos del otro.

PHP se distribuye en dos variantes, que se deciden al compilar el binario:

  • ZTS (Zend Thread Safety) — también llamada compilación Thread Safe (TS). El motor añade bloqueos y copias por hilo del estado global para que PHP pueda ejecutarse dentro de un proceso anfitrión multihilo.
  • NTS (Non-Thread-Safe) — el motor asume una solicitud por proceso y omite esa sobrecarga, lo que lo hace más rápido.

No puedes cambiar entre ellos en tiempo de ejecución, y no existe ningún mysqli_thread_safe() para activarlo o consultarlo. El tipo de compilación queda fijo cuando se elige ./configure --enable-maintainer-zts (o el equivalente en la plataforma) durante la compilación.

Por qué es una configuración en tiempo de compilación y no una función

La gente espera una función mysqli_thread_safe() porque algunas bibliotecas en C exponen una llamada mysql_thread_safe(). PHP no la incluye, porque la respuesta nunca cambia para un binario dado — consultarla en tiempo de ejecución siempre devolvería el mismo valor. Si mysqli es seguro en hilos se hereda directamente de la elección ZTS/NTS integrada en la compilación de PHP, más la biblioteca cliente subyacente (PHP moderno usa mysqlnd, el controlador nativo, que no tiene un indicador de seguridad de hilos propio).

Así que en lugar de llamar a una función, se inspecciona la compilación.

Cuándo importa realmente la seguridad de hilos

Para la gran mayoría de las aplicaciones PHP, deberías usar la compilación NTS y la seguridad de hilos no es un problema:

ConfiguraciónCompilación a usarPor qué
Nginx + PHP-FPMNTSCada trabajador es un proceso de un solo hilo; no hay hilos compartidos.
Apache con mpr_preforkNTSCada solicitud obtiene su propio proceso.
Scripts CLI, trabajos cronNTSUn proceso, un hilo.
Apache con worker / event MPM + mod_phpZTSmod_php se ejecuta dentro de los trabajadores con hilos de Apache.
Extensiones como parallel / pthreads (legado)ZTSCrean hilos PHP en un proceso.

La trampa clásica en el mundo real es Apache + mod_php en un MPM con hilos: si cargas un PHP no thread-safe en un Apache con hilos, el servidor puede colapsar o corromper datos bajo carga. Usar PHP-FPM en lugar de mod_php evita esto por completo, que es por qué FPM + NTS es el despliegue moderno estándar. Consulta la guía de instalación de PHP para saber cómo se eligen las compilaciones.

Manejo de mysqli en un contexto multihilo

Incluso en un PHP ZTS correctamente compilado, el propio objeto de conexión mysqli no está pensado para ser compartido entre hilos. Un enlace mysqli contiene resultados en búfer, estado de sentencias preparadas y un socket abierto — el uso concurrente desde dos hilos produce errores de comandos fuera de sincronía o resultados corruptos.

La regla es simple: una conexión por hilo. Abre la conexión dentro del hilo que la usa en lugar de pasar un manejador compartido.

<?php
// Each worker/thread creates and owns its own connection.
function runWorkerTask(int $workerId): void
{
    // New, independent connection for THIS thread.
    $db = new mysqli('localhost', 'user', 'password', 'shop');

    if ($db->connect_errno) {
        // Handle per-thread connection failure locally.
        error_log("Worker {$workerId} failed: {$db->connect_error}");
        return;
    }

    $result = $db->query('SELECT COUNT(*) AS total FROM orders');
    $row = $result->fetch_assoc();
    echo "Worker {$workerId} sees {$row['total']} orders\n";

    $db->close(); // Release the connection when the thread is done.
}

Para los conceptos básicos de abrir y comprobar una conexión, consulta Conectar a MySQL con mysqli y mysqli_connect_errno().

Cómo verificar la seguridad de hilos en tu entorno

Dado que no existe ninguna función en tiempo de ejecución, usa uno de estos métodos para leer la configuración de compilación.

Usando phpinfo()

Crea un script de una línea y ábrelo en el navegador, o ejecútalo desde la CLI:

<?php
phpinfo();

En la salida, busca la tabla superior y observa la fila Thread Safety (está cerca de la información de Zend Engine / compilación). Muestra enabled (ZTS) o disabled (NTS).

Verificación por línea de comandos

Desde una terminal, filtra el volcado completo de configuración:

php -i | grep "Thread Safety"

Esto imprime uno de los siguientes:

Thread Safety => enabled
Thread Safety => disabled

Dentro de código PHP en ejecución

Si quieres el valor de forma programática — para una página de diagnóstico, por ejemplo — lee la constante PHP_ZTS en lugar de buscar una función inexistente:

<?php
// PHP_ZTS is 1 on a Thread Safe (ZTS) build, 0 on a Non-Thread-Safe (NTS) build.
echo PHP_ZTS === 1 ? "Thread-safe (ZTS) build\n" : "Non-thread-safe (NTS) build\n";

Este es el reemplazo correcto y compatible para la imaginaria llamada mysqli_thread_safe().

Errores comunes

  • Llamar a mysqli_thread_safe() — no existe y lanza un Error: Call to undefined function. Usa PHP_ZTS o phpinfo() en su lugar.
  • Compartir una conexión mysqli entre hilos — abre siempre una conexión separada por hilo.
  • Cargar un PHP NTS en un MPM de Apache con hilos — adecua la compilación al servidor o migra a PHP-FPM.
  • Asumir que ZTS es "mejor" — es más lento y solo es necesario para anfitriones genuinamente con hilos; prefiere NTS en caso contrario.

Conclusión

mysqli_thread_safe() es una función que no existe. La seguridad de hilos en PHP se fija en tiempo de compilación mediante la elección de Zend Thread Safety (ZTS), no se activa ni se informa mediante una llamada en tiempo de ejecución. La mayoría de los stacks modernos (Nginx/Apache-prefork + PHP-FPM) usan la compilación NTS más rápida y nunca necesitan ZTS. Cuando necesites verificarlo, hazlo con phpinfo(), php -i | grep "Thread Safety", o la constante PHP_ZTS — y siempre dale a cada hilo su propia conexión mysqli para mantener los datos consistentes.

Práctica

Práctica
¿Qué significa que PHP sea thread-safe?
¿Qué significa que PHP sea thread-safe?
Was this page helpful?