W3docs

Função PHP pfsockopen(): Tudo o Que Você Precisa Saber

Saiba como a função pfsockopen() do PHP abre conexões de socket persistentes, seus parâmetros, exemplos práticos e a alternativa moderna recomendada.

A função pfsockopen() abre uma conexão de socket persistente na Internet ou em domínio Unix. "Persistente" significa que o socket subjacente é mantido aberto após o término do script e reutilizado por requisições posteriores que se conectam ao mesmo host e porta — economizando o custo de abrir uma nova conexão (consulta DNS, handshake TCP) a cada vez.

Importante: pfsockopen() foi descontinuada no PHP 8.1 e removida no PHP 8.2, portanto não está disponível no PHP moderno. Este capítulo documenta seu comportamento histórico e mostra o que usar em seu lugar. Se você está no PHP 8.2+, vá para Alternativa moderna.

Este capítulo aborda o que pfsockopen() fazia, sua sintaxe e parâmetros, um exemplo HTTP prático, a diferença entre sockets persistentes e não persistentes, armadilhas comuns e a substituição recomendada.

O que é a Função pfsockopen()?

pfsockopen() ("persistent fsockopen") é a versão persistente de fsockopen(). Ambas abrem um socket de baixo nível e retornam um stream do qual você pode ler e no qual pode escrever com as funções de arquivo habituais. A única diferença: uma conexão aberta com fsockopen() é fechada ao final da requisição, enquanto uma aberta com pfsockopen() é agrupada pelo processo PHP e reutilizada em requisições subsequentes para o mesmo destino.

Isso a tornava útil em configurações de longa duração (workers FPM/mod_php) onde o mesmo script conversava repetidamente com o mesmo backend — por exemplo, um nó memcached ou um serviço TCP personalizado — e o overhead do handshake por requisição valia a pena evitar.

Como Usar a Função pfsockopen()

Veja a sintaxe da função:

A sintaxe PHP da Função pfsockopen()

pfsockopen($hostname, $port, &$errno, &$errstr, $timeout);

A função aceita cinco parâmetros:

  • $hostname: O hostname ou endereço IP do servidor ao qual se conectar.
  • $port: O número da porta para conexão.
  • $errno: Uma variável passada por referência que será definida com o número do erro caso ocorra um erro.
  • $errstr: Uma variável passada por referência que será definida com a mensagem de erro caso ocorra um erro.
  • $timeout: O período de timeout em segundos.

Apenas $hostname e $port são obrigatórios; $errno, $errstr e $timeout são opcionais, mas quase sempre vale a pena passá-los para diagnosticar falhas.

Valor de retorno: Retorna um stream/resource em caso de sucesso, ou false em caso de falha.

Veja um exemplo de como usar a função pfsockopen() para criar uma conexão de socket persistente, tratar erros e trocar dados:

Como Usar a Função pfsockopen()?

<?php

$hostname = "example.com";
$port = 80;
$errno = 0;
$errstr = "";
$timeout = 30;

$socket = pfsockopen($hostname, $port, $errno, $errstr, $timeout);

if ($socket === false) {
    echo "Connection failed: $errno - $errstr";
} else {
    fwrite($socket, "GET / HTTP/1.1\r\nHost: $hostname\r\n\r\n");
    $response = fread($socket, 2048);
    echo $response;
    fclose($socket);
}
?>

Aqui abrimos uma conexão com example.com na porta 80 com um timeout de 30 segundos. Em caso de falha, o número e a mensagem do erro ficam em $errno/$errstr. Uma vez conectado, enviamos uma requisição HTTP bruta com fwrite(), lemos a resposta com fread() e fechamos o handle com fclose().

Um stream retornado se comporta como qualquer outro stream PHP, portanto as mesmas funções de I/O que você usa com fopen() funcionam aqui também.

Sockets Persistentes vs. Não Persistentes

A tabela abaixo mostra quando cada comportamento importa:

Aspectofsockopen()pfsockopen()
Tempo de vida da conexãoFechada ao final da requisiçãoAgrupada e reutilizada entre requisições
Custo na primeira requisiçãoHandshake completo a cada vezHandshake completo apenas na primeira requisição
Melhor paraScripts únicos ou de curta duraçãoChamadas repetidas ao mesmo backend em workers de longa duração

A persistência só ajuda quando o mesmo processo atende muitas requisições para o mesmo host/porta — tipicamente PHP-FPM ou mod_php. Em scripts CLI que terminam imediatamente, não há nada a reutilizar, então pfsockopen() se comporta como fsockopen().

Armadilhas Comuns

  • fclose() não fecha de verdade. Chamar fclose() em um socket persistente apenas o retorna ao pool. Esse é o objetivo — mas significa que uma conexão meio quebrada pode ser entregue à próxima requisição. Sempre valide a conexão (ou envie um ping leve) antes de confiar nela.
  • Sem multiplexação. Cada worker PHP mantém seu próprio pool, portanto o número de sockets persistentes cresce com a contagem de workers. Um servidor ocupado pode esgotar o limite de conexões do backend.
  • Vazamento de estado. Como o socket sobrevive entre requisições, dados em buffer remanescentes ou um estado de protocolo no meio de uma requisição anterior podem corromper a próxima. Sockets persistentes são mais adequados para protocolos simples de requisição/resposta sem estado.
  • Removida no PHP 8.2. Código que ainda chama pfsockopen() lançará um erro fatal Call to undefined function no PHP 8.2+.

Alternativa Moderna

No PHP 8.2+, use stream_socket_client() com a flag STREAM_CLIENT_PERSISTENT. É mais flexível (suporta transportes tcp://, tls:// e unix:// e contextos de stream) e é a API ativamente mantida:

<?php

$socket = stream_socket_client(
    "tcp://example.com:80",
    $errno,
    $errstr,
    30,
    STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT
);

if ($socket === false) {
    echo "Connection failed: $errno - $errstr";
} else {
    fwrite($socket, "GET / HTTP/1.1\r\nHost: example.com\r\nConnection: close\r\n\r\n");
    echo fread($socket, 2048);
    fclose($socket);
}
?>

Para trabalho HTTP cotidiano, um cliente de nível mais alto como cURL ou Guzzle costuma ser a melhor escolha — recorra a sockets brutos apenas quando precisar de um protocolo personalizado.

Conclusão

pfsockopen() criava uma conexão de socket persistente e reutilizável — útil para workers PHP de longa duração que contatavam repetidamente o mesmo backend. Sua característica principal era que fclose() retornava o socket ao pool em vez de fechá-lo. Como a função foi removida no PHP 8.2, novos códigos devem usar stream_socket_client() com STREAM_CLIENT_PERSISTENT. Para explorar I/O de stream relacionado, veja fsockopen(), fwrite() e fread().

Prática

Prática
O que a função 'pfsockopen' faz no PHP?
O que a função 'pfsockopen' faz no PHP?
Was this page helpful?