W3docs

pclose()

PHP propose pclose() pour fermer un pointeur de fichier de processus ouvert par popen() et récupérer le code de sortie du processus.

La fonction PHP pclose()

La fonction PHP pclose() ferme un pointeur de fichier de processus — le flux spécial renvoyé par popen() lorsque vous lancez une commande externe. Là où fclose() se contente de fermer un descripteur de fichier ordinaire, pclose() fait quelque chose de plus : elle attend que le processus sous-jacent se termine et vous renvoie son code de sortie.

Cette page couvre la syntaxe, la valeur de retour (ainsi qu'un piège subtil à ce sujet), un exemple complet de lecture puis fermeture, et quand vous devriez préférer proc_open().

Pourquoi pclose() existe

popen() exécute une commande shell et vous donne un canal pour y envoyer des données (mode 'w') ou en lire la sortie (mode 'r'). Ce canal est adossé à un vrai processus du système d'exploitation. Si vous abandonnez simplement le descripteur — ou le fermez avec la mauvaise fonction — le processus peut rester en état de zombie et son code de sortie est perdu. pclose() est le pendant approprié : elle vide le canal, attend que le processus enfant se termine, le récupère et renvoie le code de sortie pour que votre script puisse réagir à la réussite ou à l'échec.

Associez toujours chaque popen() à un pclose(). Utiliser fclose() sur un descripteur issu de popen() est un comportement indéfini.

Syntaxe

pclose(resource $handle): int

Paramètres

La fonction prend un seul paramètre :

  • $handle — le pointeur de fichier de processus renvoyé par popen(). Passer tout autre type de ressource est invalide.

Valeur de retour

pclose() renvoie le statut de terminaison du processus sous forme d'entier (il s'agit de la valeur brute issue de l'appel C pclose — sur la plupart des systèmes, le code de sortie réel se trouve dans l'octet de poids fort). Elle renvoie -1 si le processus n'a pas pu être récupéré. Sur les anciennes versions de PHP, passer un descripteur invalide émet un avertissement et renvoie FALSE.

Pour obtenir le code de sortie brut sur un système de type Unix, décalez la valeur de 8 bits vers la droite :

$status   = pclose($handle);
$exitCode = $status >> 8;   // 0 means the command succeeded

Exemple

Ouvrez une commande, lisez sa sortie, puis fermez le canal et examinez le résultat :

<?php

// Run an external command and read its output.
$handle = popen('ls -la', 'r');

if ($handle === false) {
    die("Failed to start the command.\n");
}

$output = '';
while (!feof($handle)) {
    $output .= fread($handle, 1024);
}

echo $output;

// Close the pipe and capture the process exit status.
$status   = pclose($handle);
$exitCode = $status >> 8;

echo "Command exited with code: $exitCode\n";

Nous ouvrons un pointeur de fichier de processus avec popen(), lisons la sortie complète dans une boucle avec fread() (un seul fread peut ne pas tout capturer pour des sorties volumineuses), puis fermons le canal avec pclose() et décodons le code de sortie. Un code de sortie de 0 signifie conventionnellement un succès.

Pièges courants

  • Ne mélangez pas fclose() et pclose(). Un descripteur issu de popen() doit être fermé avec pclose(), et un descripteur issu de fopen() avec fclose().
  • pclose() est bloquante. Elle attend que le processus enfant se termine. Si la commande ne se termine jamais, votre script se bloque.
  • Lisez avant de fermer. pclose() peut ignorer toute sortie tamponée non lue, donc terminez la lecture du canal en premier.
  • Un sens par canal. Un canal popen() est soit lisible, soit inscriptible, mais pas les deux — pour une communication bidirectionnelle, vous avez besoin de proc_open().

Quand utiliser proc_open() à la place

popen()/pclose() sont parfaits pour une commande ponctuelle rapide où vous n'avez besoin que de sa sortie ou devez lui envoyer des données. Lorsque vous avez besoin des deux à la fois, de la séparation de stdout et stderr, d'un contrôle de l'environnement ou d'un répertoire de travail, utilisez proc_open() — il vous donne un contrôle bidirectionnel complet sur le processus lancé.

Conclusion

pclose() est le compagnon indispensable de popen() : il ferme le canal de processus, attend la fin de la commande et renvoie son code de sortie pour que vous puissiez vérifier que la commande a réussi. Associez toujours les deux, lisez le canal avant de le fermer et n'oubliez pas de décaler le statut de 8 bits vers la droite pour lire le vrai code de sortie sur les systèmes Unix. Pour tout ce qui dépasse un canal unidirectionnel, utilisez proc_open().

Practice

Pratique
Quelle est la fonction de pclose() en PHP ?
Quelle est la fonction de pclose() en PHP ?
Was this page helpful?