W3docs

Fonction PHP pfsockopen() : Tout ce que vous devez savoir

Découvrez la fonction PHP pfsockopen() : syntaxe, paramètres, exemple HTTP, différences avec fsockopen() et l'alternative moderne recommandée.

La fonction pfsockopen() ouvre une connexion socket Internet ou de domaine Unix persistante. « Persistante » signifie que le socket sous-jacent reste ouvert après la fin du script et est réutilisé par les requêtes ultérieures qui se connectent au même hôte et au même port — ce qui évite le coût d'ouverture d'une nouvelle connexion (résolution DNS, établissement TCP) à chaque fois.

Important : pfsockopen() a été dépréciée en PHP 8.1 et supprimée en PHP 8.2, elle n'est donc pas disponible dans les versions modernes de PHP. Ce chapitre documente son comportement historique et présente ce qu'il faut utiliser à la place. Si vous êtes sur PHP 8.2+, passez directement à Alternative moderne.

Ce chapitre couvre ce que faisait pfsockopen(), sa syntaxe et ses paramètres, un exemple HTTP concret, la différence entre sockets persistants et non persistants, les pièges courants, ainsi que le remplacement recommandé.

Qu'est-ce que la fonction pfsockopen() ?

pfsockopen()persistent fsockopen ») est la version persistante de fsockopen(). Les deux ouvrent un socket de bas niveau et retournent un flux que vous pouvez lire et écrire avec les fonctions de fichier habituelles. La seule différence : une connexion ouverte avec fsockopen() est fermée à la fin de la requête, tandis qu'une connexion ouverte avec pfsockopen() est mise en pool par le processus PHP et réutilisée pour les requêtes suivantes vers la même destination.

Cela la rendait utile dans des configurations à longue durée de vie (workers FPM/mod_php) où le même script communiquait répétitivement avec le même backend — par exemple un nœud memcached ou un service TCP personnalisé — et où le coût de la négociation par requête valait la peine d'être évité.

Comment utiliser la fonction pfsockopen() ?

Voici la syntaxe de la fonction :

La syntaxe PHP de la fonction pfsockopen()

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

La fonction prend cinq paramètres :

  • $hostname : Le nom d'hôte ou l'adresse IP du serveur auquel se connecter.
  • $port : Le numéro de port auquel se connecter.
  • $errno : Une variable passée par référence qui sera définie avec le numéro d'erreur si une erreur survient.
  • $errstr : Une variable passée par référence qui sera définie avec le message d'erreur si une erreur survient.
  • $timeout : Le délai d'expiration en secondes.

Seuls $hostname et $port sont obligatoires ; $errno, $errstr et $timeout sont optionnels mais presque toujours utiles à passer pour diagnostiquer les échecs.

Valeur de retour : Retourne un flux/ressource en cas de succès, ou false en cas d'échec.

Voici un exemple d'utilisation de la fonction pfsockopen() pour créer une connexion socket persistante, gérer les erreurs et échanger des données :

Comment utiliser la fonction 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);
}
?>

Ici, nous ouvrons une connexion vers example.com sur le port 80 avec un délai d'expiration de 30 secondes. En cas d'échec, le numéro et le message d'erreur sont stockés dans $errno/$errstr. Une fois connecté, nous envoyons une requête HTTP brute avec fwrite(), lisons la réponse avec fread(), et fermons le descripteur avec fclose().

Un flux retourné se comporte comme n'importe quel autre flux PHP, ainsi les mêmes fonctions d'E/S que vous utilisez avec fopen() fonctionnent également ici.

Sockets persistants vs. non persistants

Le tableau ci-dessous montre dans quels cas chaque comportement est pertinent :

Aspectfsockopen()pfsockopen()
Durée de vie de la connexionFermée à la fin de la requêteMise en pool et réutilisée entre les requêtes
Coût de la première requêteNégociation complète à chaque foisNégociation complète uniquement lors de la première requête
Idéal pourScripts ponctuels ou courtsAppels répétés vers le même backend dans des workers à longue durée de vie

La persistance n'est utile que lorsque le même processus traite de nombreuses requêtes vers le même hôte/port — typiquement PHP-FPM ou mod_php. Dans les scripts CLI qui se terminent immédiatement, il n'y a rien à réutiliser, donc pfsockopen() se comporte comme fsockopen().

Pièges courants

  • fclose() ne ferme pas vraiment le socket. Appeler fclose() sur un socket persistant le remet simplement dans le pool. C'est le but — mais cela signifie qu'une connexion à moitié défectueuse peut être transmise à la requête suivante. Validez toujours la connexion (ou envoyez un ping léger) avant de vous y fier.
  • Pas de multiplexage. Chaque worker PHP maintient son propre pool, donc le nombre de sockets persistants augmente avec le nombre de workers. Un serveur très sollicité peut épuiser la limite de connexions du backend.
  • Fuite d'état. Comme le socket survit entre les requêtes, des données en tampon résiduelles ou un état intermédiaire de protocole d'une requête précédente peuvent corrompre la suivante. Les sockets persistants conviennent mieux aux protocoles requête/réponse simples et sans état.
  • Supprimée en PHP 8.2. Le code qui appelle encore pfsockopen() lèvera une erreur fatale Call to undefined function sur PHP 8.2+.

Alternative moderne

Sur PHP 8.2+, utilisez stream_socket_client() avec l'indicateur STREAM_CLIENT_PERSISTENT. Elle est plus flexible (supporte les transports tcp://, tls:// et unix:// ainsi que les contextes de flux) et constitue l'API activement maintenue :

<?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);
}
?>

Pour les travaux HTTP courants, un client de niveau supérieur tel que cURL ou Guzzle est généralement le meilleur choix — n'utilisez les sockets bruts que lorsque vous avez besoin d'un protocole personnalisé.

Conclusion

pfsockopen() créait une connexion socket persistante et réutilisable — pratique pour les workers PHP à longue durée de vie qui contactaient répétitivement le même backend. Sa caractéristique principale était que fclose() renvoyait le socket dans un pool au lieu de le fermer. Puisque la fonction a été supprimée en PHP 8.2, le nouveau code doit utiliser stream_socket_client() avec STREAM_CLIENT_PERSISTENT. Pour explorer les E/S de flux associées, consultez fsockopen(), fwrite() et fread().

Practice

Pratique
Que fait la fonction 'pfsockopen' en PHP ?
Que fait la fonction 'pfsockopen' en PHP ?
Was this page helpful?