Introdução: por que programação de rede em PHP não é assustadora, mas sim interessante
\n\nQuando se ouve "programação de rede", logo vêm à mente imagens de desenvolvedores C++ lidando com sockets de baixo nível ou administradores escrevendo scripts em Python para monitorar a rede. E o PHP? Será que seu papel é apenas exibir "Hello, World!" em um site?
\n\nNa verdade, o PHP é uma ferramenta poderosa para comunicação em rede. Ele consegue abrir sockets, fazer requisições HTTP, trabalhar com WebSocket e até mesmo fazer scraping de outros sites. E tudo isso — sem precisar instalar extensões adicionais (bem, quase).
\n\nNeste artigo, vamos explorar as principais técnicas de programação de rede em PHP. Você aprenderá como criar um cliente TCP simples, automatizar requisições a APIs, fazer scraping de sites e construir seu próprio chat com WebSocket. Vamos nessa!
\n\n1. Fundamentos de Sockets em PHP
\n\nSockets são uma forma de baixo nível para programas se comunicarem pela rede. No PHP, o trabalho com sockets é feito através das funções da família socket_*. Elas estão presentes na instalação padrão, mas às vezes é necessário habilitar a extensão sockets no php.ini.
Criando um Cliente TCP
\n\nVamos criar um cliente simples que se conecta a um servidor (por exemplo, ao time.nist.gov — servidor de hora exata) e lê a resposta:
\n\n<?php\n$host = 'time.nist.gov';\n$port = 37;\n\n// Criando o socket\n$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);\nif ($socket === false) {\n echo "Falha ao criar socket: " . socket_strerror(socket_last_error()) . "\\n";\n exit;\n}\n\n// Conectando\n$result = socket_connect($socket, $host, $port);\nif ($result === false) {\n echo "Falha ao conectar: " . socket_strerror(socket_last_error($socket)) . "\\n";\n exit;\n}\n\n// Lendo 4 bytes (hora no formato NTP)\n$bytes = socket_read($socket, 4);\nif ($bytes === false) {\n echo "Erro de leitura: " . socket_strerror(socket_last_error($socket)) . "\\n";\n exit;\n}\n\n// Fechando o socket\nsocket_close($socket);\n\n// Convertendo dados binários para número\n$time = unpack('N', $bytes)[1];\n// O tempo NTP é contado a partir de 1900, subtraímos 70 anos (em segundos)\n$unix_time = $time - 2208988800;\necho "Hora atual (UNIX): " . date('Y-m-d H:i:s', $unix_time) . "\\n";\n?>\n\nEste código se conecta ao servidor de hora exata, lê 4 bytes (hora no formato NTP) e os converte em uma data legível. Observe o tratamento de erros — em programação de rede, isso é essencial.
\n\nCriando um Servidor TCP Simples
\n\nAgora, vamos criar nosso próprio mini-servidor que aceita conexões e responde com "Hello, client!":
\n\n<?php\n$host = '127.0.0.1';\n$port = 8080;\n\n$server = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);\nsocket_bind($server, $host, $port);\nsocket_listen($server, 5);\n\necho "Servidor rodando em $host:$port\\n";\n\nwhile (true) {\n $client = socket_accept($server);\n if ($client === false) {\n continue;\n }\n $msg = "Hello, client!\\n";\n socket_write($client, $msg, strlen($msg));\n socket_close($client);\n}\nsocket_close($server);\n?>\n\nExecute o script no terminal (php server.php) e depois conecte-se via telnet: telnet 127.0.0.1 8080. Você verá a saudação.
Dica: Para projetos reais, use bibliotecas prontas como ReactPHP ou Amp — elas oferecem assincronicidade e uma API mais amigável.
2. Requisições HTTP com cURL
\n\ncURL é o canivete suíço para trabalhar com HTTP em PHP. Ele faz requisições GET, POST, lida com cookies, cabeçalhos, proxies e certificados. A extensão curl geralmente já vem instalada.
Requisição GET Básica
\n\n<?php\n$ch = curl_init('https://api.github.com/repos/php/php-src');\ncurl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\ncurl_setopt($ch, CURLOPT_USERAGENT, 'PHP Script');\n$response = curl_exec($ch);\n$http_code = curl_getinf