PHP exec () vs system () vs passthru ()

312

Quelles sont les différences?

Existe-t-il une situation ou une raison spécifique pour chaque fonction? Si oui, pouvez-vous donner quelques exemples de ces situations?

PHP.net dit qu'ils sont utilisés pour exécuter des programmes externes. voir référence D'après les exemples que je vois, je ne vois aucune différence évidente.

Si je devais simplement exécuter un script (bash ou python), quelle fonction me recommandez-vous d'utiliser?

codingbear
la source
16
Il y a aussi proc_open()et popen(), les deux permettant un plus haut degré de contrôle sur le processus engendré.
Christian

Réponses:

195

Ils ont des objectifs légèrement différents.

  • exec() sert à appeler une commande système et peut-être à gérer vous-même la sortie.
  • system() sert à exécuter une commande système et à afficher immédiatement la sortie - vraisemblablement du texte.
  • passthru() sert à exécuter une commande système dont vous souhaitez le retour brut - probablement quelque chose de binaire.

Quoi qu'il en soit, je vous suggère de ne pas en utiliser. Ils produisent tous du code hautement non transférable.

Kalium
la source
147
Parfois, la portabilité doit être sacrifiée pour la fonctionnalité. Il y a certaines choses que PHP ne peut pas bien faire.
Frank Crook
30
@ Kalium: pouvez-vous en dire plus sur votre déclaration? le simple fait de donner de vagues statistiques en pourcentage ne me convainc pas. Je crois que l'utilisation d'appels système pour exécuter des scripts est tout à fait correcte tant que l'application entière ne dépend pas d'un tas de scripts dans le back-end.
codingbear
46
@Christian izkata@izein:~$ dir -bash: dir: command not found- FreeBSD
Izkata
5
@OZ_ Je suis arrivé à la situation où j'ai dû faire des calculs très coûteux. Aucun module PHP n'était (n'est) disponible pour cela. J'ai écrit mon propre programme C et je l'invoque avec passthru (). Parfois, la portabilité peut être moins importante que d'autres choses. Dépend du projet.
Paolo
9
Aussi, il est une erreur de penser que PHP est portable aussi longtemps que vous évitez exec, system, passthru. Le code PHP dépend de l'environnement dans lequel il s'exécute, et de nombreux bogues de sécurité sont dus au fait de ne pas en tenir compte. Voici un exemple rapide: stackoverflow.com/questions/3003145/…
Pacerier
131

Tiré de http://php.net/ && Chipmunkninja :

Le système () Fonction

La fonction système en PHP prend un argument de chaîne avec la commande à exécuter ainsi que tous les arguments que vous souhaitez transmettre à cette commande. Cette fonction exécute la commande spécifiée et transfère tout texte résultant dans le flux de sortie (soit la sortie HTTP dans une situation de serveur Web, soit la console si vous exécutez PHP comme outil de ligne de commande). Le retour de cette fonction est la dernière ligne de sortie du programme, si elle émet une sortie texte.

Le exec () Fonction

La fonction système est assez utile et puissante, mais l'un des plus gros problèmes est que tout le texte résultant du programme va directement au flux de sortie. Dans certains cas, vous souhaiterez peut-être formater le texte résultant et l'afficher d'une manière différente, ou ne pas l'afficher du tout.

Pour cela, la fonction exec en PHP est parfaitement adaptée. Au lieu de vider automatiquement tout le texte généré par le programme en cours d'exécution dans le flux de sortie, cela vous donne la possibilité de placer ce texte dans un tableau renvoyé dans le deuxième paramètre de la fonction:

Le shell_exec () Fonction

La plupart des programmes que nous avons exécutés jusqu'à présent étaient, plus ou moins, de vrais programmes1. Cependant, l'environnement dans lequel les utilisateurs Windows et Unix opèrent est en réalité beaucoup plus riche que cela. Les utilisateurs de Windows ont la possibilité d'utiliser le programme d'invite de commandes Windows, cmd.exe Ce programme est appelé shell de commande.

Le passthru () Fonction

Une fonction fascinante que PHP fournit similaire à celles que nous avons vues jusqu'à présent est la fonction passthru. Cette fonction, comme les autres, exécute le programme auquel vous le demandez. Cependant, il procède ensuite à l'envoi immédiat de la sortie brute de ce programme vers le flux de sortie avec lequel PHP travaille actuellement (c'est-à-dire HTTP dans un scénario de serveur Web ou le shell dans une version en ligne de commande de PHP).

Le proc_open () Fonction et popen () fonction

proc_open () est similaire à popen () mais offre un plus grand degré de contrôle sur l'exécution du programme. cmd est la commande à exécuter par le shell. descriptorspec est un tableau indexé où la clé représente le numéro du descripteur et la valeur représente la façon dont PHP transmettra ce descripteur au processus enfant. les tuyaux seront définis sur un tableau indexé de pointeurs de fichiers qui correspondent à la fin de PHP de tous les tuyaux créés. La valeur de retour est une ressource représentant le processus; vous devez le libérer à l'aide de proc_close () lorsque vous en aurez terminé.

Dinesh Saini
la source
6
La vitesse d'exécution shell_exec est plus rapide que les autres alternatives.
Dinesh Saini
29
Vous devez mentionner que vous avez copié votre réponse directement depuis ChipmunkNinja .
TachyonVortex
7
@TachyonVortex, heureusement, il a copié la réponse textuellement, car ChipmunkNinja n'existe plus.
Phileo99
2
Il y a une copie de cet article dans la machine de retour: web.archive.org/web/20130809032648/http://chipmunkninja.com/…
bagonyi
2
Qu'en est-il de popen et proc_open?
CMCDragonkai
103

Les réponses précédentes semblent toutes un peu confuses ou incomplètes, alors voici un tableau des différences ...

+----------------+-----------------+----------------+----------------+
|    Command     | Displays Output | Can Get Output | Gets Exit Code |
+----------------+-----------------+----------------+----------------+
| system()       | Yes (as text)   | Last line only | Yes            |
| passthru()     | Yes (raw)       | No             | Yes            |
| exec()         | No              | Yes (array)    | Yes            |
| shell_exec()   | No              | Yes (string)   | No             |
| backticks (``) | No              | Yes (string)   | No             |
+----------------+-----------------+----------------+----------------+
  • "Affiche la sortie" signifie qu'il diffuse la sortie vers le navigateur (ou la sortie de ligne de commande si elle s'exécute à partir d'une ligne de commande).
  • "Peut obtenir une sortie" signifie que vous pouvez obtenir la sortie de la commande et l'affecter à une variable PHP.
  • Le "code de sortie" est une valeur spéciale renvoyée par la commande (également appelée "état de retour"). Zéro signifie généralement qu'il a réussi, les autres valeurs sont généralement des codes d'erreur.

Autres choses diverses à savoir:

  • Le shell_exec () et l'opérateur backticks font la même chose.
  • Il existe également proc_open () et popen () qui vous permettent de lire / écrire de manière interactive des flux avec une commande d'exécution.
  • Ajoutez "2> & 1" à la chaîne de commande si vous souhaitez également capturer / afficher les messages d'erreur.
  • Utilisez escapeshellcmd () pour échapper les arguments de commande qui peuvent contenir des caractères problématiques.
  • Si vous passez une variable $ output à exec () pour stocker la sortie, si $ output n'est pas vide, il y ajoutera la nouvelle sortie. Il vous faudra donc peut-être d'abord désactiver ($ output).
orrd
la source
lesquels peuvent exécuter un fichier php?
johny pourquoi
1
@johnywhy aucun en soi - sauf si vous invoquez explicitement le php cli ou autre. Je suppose que vous voulez includeet vos amis
Hagen von Eitzen
21

Tout dépend vraiment de la façon dont vous voulez gérer la sortie que la commande peut retourner et si vous voulez que votre script PHP attende que le programme appelé se termine ou non.

  • exec exécute une commande et transmet la sortie à l'appelant (ou la renvoie dans une variable facultative).

  • passthruest similaire à la exec()fonction en ce sens qu'elle exécute une commande. Cette fonction doit être utilisée à la place exec()ou system()lorsque la sortie de la commande Unix est une donnée binaire qui doit être retransmise directement au navigateur.

  • system exécute un programme externe et affiche la sortie, mais uniquement la dernière ligne.

Si vous devez exécuter une commande et que toutes les données de la commande soient retransmises directement sans aucune interférence, utilisez la passthru()fonction.

Cody Caughlan
la source
8

Si vous exécutez votre script PHP à partir de la ligne de commande, cela passthru()présente un gros avantage. Il vous permettra d' exécuter des scripts / programmes tels que vim, dialog, etc., laissant les programmes de contrôle de la poignée et revenir à votre script seulement quand ils sont faits.

Si vous utilisez system()ou exec()pour exécuter ces scripts / programmes, cela ne fonctionnera tout simplement pas.

Gotcha: Pour une raison quelconque, vous ne pouvez pas exécuter lessavec passthru()en PHP.

Mat
la source
1
Je ne comprends pas ce que tu dis. Vous pouvez exécuter des programmes à la fois depuis CLI et (F) CGI (ainsi que mod_php). Il peut y avoir des restrictions imposées par le système, telles que selinux. Mais un système bien mis en place les désactivera de manière sélective. Bien sûr, un hôte partagé est une histoire différente, mais vous n'offrirez pas non plus un environnement partagé à des clients estimés, non?
Christian