W3docs

Guia Completo sobre a Função mysqli_thread_safe em PHP

Saiba o que significa thread-safe em PHP, por que mysqli_thread_safe() não existe e como verificar a segurança de threads no seu ambiente.

Ao trabalhar com bancos de dados MySQL em PHP através da extensão mysqli, uma dúvida que surge frequentemente é: "O mysqli é thread-safe e existe uma função mysqli_thread_safe() que posso chamar para verificar?"

A resposta curta é que mysqli_thread_safe() não é uma função em PHP, e a segurança de threads não é algo que se consulta em tempo de execução. É uma propriedade de como seu binário PHP foi compilado. Este guia explica o que "thread-safe" realmente significa para PHP, por que a segurança de threads do mysqli é uma decisão em tempo de compilação, quando isso importa na prática e como verificar no seu ambiente.

O Que "Thread-Safe" Significa em PHP

Um programa é thread-safe quando múltiplas threads podem executar o mesmo código ao mesmo tempo sem corromper dados compartilhados. Em uma compilação thread-safe, o motor PHP protege o estado global interno (a tabela de símbolos, o gerenciador de memória, as variáveis globais das extensões, etc.) para que duas threads executando dentro do mesmo processo não corrompam os dados uma da outra.

PHP é distribuído em dois sabores, decididos quando o binário é compilado:

  • ZTS (Zend Thread Safety) — também chamado de compilação Thread Safe (TS). O motor adiciona bloqueios e cópias por thread do estado global para que PHP possa rodar dentro de um processo hospedeiro multi-thread.
  • NTS (Non-Thread-Safe) — o motor assume uma requisição por processo e ignora essa sobrecarga, tornando-se mais rápido.

Não é possível alternar entre eles em tempo de execução, e não existe mysqli_thread_safe() para alternar ou reportar isso. O tipo de compilação é fixo quando ./configure --enable-maintainer-zts (ou o equivalente da plataforma) é escolhido durante a compilação.

Por Que É uma Configuração em Tempo de Compilação, Não uma Função

As pessoas esperam uma função mysqli_thread_safe() porque algumas bibliotecas C expõem uma chamada mysql_thread_safe(). PHP não oferece uma, porque a resposta nunca muda para um dado binário — consultá-la em tempo de execução sempre retornaria o mesmo valor. Se mysqli é seguro em threads é herdado diretamente da escolha ZTS/NTS incorporada na compilação PHP, mais a biblioteca cliente subjacente (o PHP moderno usa mysqlnd, o driver nativo, que não tem toggle separado de segurança de threads).

Portanto, em vez de chamar uma função, você inspeciona a compilação.

Quando a Segurança de Threads Realmente Importa

Para a grande maioria das aplicações PHP, você deve usar a compilação NTS e a segurança de threads não é um problema:

ConfiguraçãoCompilação a usarPor quê
Nginx + PHP-FPMNTSCada worker é um processo single-thread; sem threads compartilhadas.
Apache com mpr_preforkNTSCada requisição tem seu próprio processo.
Scripts CLI, cron jobsNTSUm processo, uma thread.
Apache com worker / event MPM + mod_phpZTSmod_php roda dentro dos workers com threads do Apache.
ext como parallel / pthreads (legado)ZTSEles criam threads PHP em um processo.

A armadilha clássica do mundo real é Apache + mod_php em um MPM com threads: se você carregar um PHP não thread-safe em um Apache com threads, o servidor pode travar ou corromper dados sob carga. Usar PHP-FPM em vez de mod_php contorna isso completamente, que é por isso que FPM + NTS é o deployment moderno padrão. Veja o guia de instalação do PHP para saber como as compilações são escolhidas.

Tratando mysqli em um Contexto Multi-Thread

Mesmo em um PHP ZTS corretamente compilado, o objeto de conexão mysqli em si não é destinado a ser compartilhado entre threads. Um link mysqli mantém resultados em buffer, estado de prepared statements e um socket aberto — o uso concorrente de duas threads produz erros de comandos fora de sincronia ou resultados incorretos.

A regra é simples: uma conexão por thread. Abra a conexão dentro da thread que a usa em vez de passar um handle compartilhado.

<?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 os conceitos básicos de abrir e verificar uma conexão, veja Conectar ao MySQL com mysqli e mysqli_connect_errno().

Como Verificar a Segurança de Threads no Seu Ambiente

Como não há função em tempo de execução, use uma destas opções para ler a configuração da compilação.

Usando phpinfo()

Crie um script de uma linha e abra-o no navegador, ou execute-o a partir da CLI:

<?php
phpinfo();

Na saída, encontre a tabela superior e olhe para a linha Thread Safety (fica próximo às informações do Zend Engine / compilação). Ela exibe enabled (ZTS) ou disabled (NTS).

Verificação pela Linha de Comando

Em um terminal, filtre o dump completo da configuração:

php -i | grep "Thread Safety"

Isso imprime um dos seguintes:

Thread Safety => enabled
Thread Safety => disabled

Dentro do Código PHP em Execução

Se você quiser o valor programaticamente — para uma página de diagnósticos, por exemplo — leia a constante PHP_ZTS em vez de procurar uma função 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 é o substituto correto e suportado para a imaginária chamada mysqli_thread_safe().

Erros Comuns

  • Chamar mysqli_thread_safe() — ela não existe e lança um Error: Call to undefined function. Use PHP_ZTS ou phpinfo() em vez disso.
  • Compartilhar uma conexão mysqli entre threads — sempre abra uma conexão separada por thread.
  • Carregar um PHP NTS em um Apache MPM com threads — corresponda a compilação ao servidor, ou migre para PHP-FPM.
  • Assumir que ZTS é "melhor" — é mais lento e só é necessário para hosts genuinamente com threads; prefira NTS caso contrário.

Conclusão

mysqli_thread_safe() é uma função que não existe. A segurança de threads em PHP é fixada em tempo de compilação pela escolha do Zend Thread Safety (ZTS), não alternada ou reportada por uma chamada em tempo de execução. A maioria das stacks modernas (Nginx/Apache-prefork + PHP-FPM) usa a compilação mais rápida NTS e nunca precisa de ZTS. Quando você precisar verificar, leia com phpinfo(), php -i | grep "Thread Safety", ou a constante PHP_ZTS — e sempre dê a cada thread sua própria conexão mysqli para manter os dados consistentes.

Prática

Prática
O que significa PHP ser thread-safe?
O que significa PHP ser thread-safe?
Was this page helpful?