2009-04-09 8 views
258

Quelles sont les différences?PHP exec() vs système() vs passthru()

Y a-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. D'après les exemples que je vois, je ne vois pas de différence évidente.

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

+12

Il y a aussi 'proc_open()' et 'popen()', qui permettent un plus haut degré de contrôle sur le processus engendré. – Christian

Répondre

157

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

  • exec() est d'appeler une commande système, et peut-être gérer la sortie vous-même.
  • system() est d'exécuter une commande système et d'afficher immédiatement la sortie - vraisemblablement du texte.
  • passthru() est d'exécuter une commande système dont vous souhaitez que le brut retourne - probablement quelque chose de binaire. Quoiqu'il en soit, je vous suggère de ne pas utiliser l'un d'entre eux

Ils produisent tous du code hautement non portable.

+128

Parfois, la portabilité doit être sacrifiée pour la fonctionnalité. Il y a certaines choses que PHP ne peut pas bien faire. –

+9

Certes, mais 95% du temps les gens veulent utiliser un appel de shell, les raisons sont toutes fausses. – Kalium

+28

@Kalium: pouvez-vous élaborer davantage sur votre déclaration? le simple fait d'indiquer de vagues statistiques sur les pourcentages ne me convainc pas. Je crois que l'utilisation des appels système pour exécuter des scripts est tout à fait bien tant que l'ensemble de l'application ne dépend pas d'un tas de scripts dans le back-end. – codingbear

17

Tout se résume à la façon dont vous voulez gérer la sortie que la commande pourrait renvoyer et si vous voulez que votre script PHP attende que le programme callee soit terminé ou non.

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

  • passthru est similaire à la fonction exec() en ce qu'il exécute une commande. Cette fonction doit être utilisée à la place de exec() ou system() lorsque la sortie de la commande Unix est une donnée binaire qui doit être transmise directement au navigateur. Exécute un programme externe et affiche la sortie, mais seulement la dernière ligne.

Si vous avez besoin d'exécuter une commande et d'avoir toutes les données de la commande passée directement sans aucun traitement, utilisez la fonction passthru().

5

Si vous exécutez votre script PHP à partir de la ligne de commande, passthru() a un grand avantage. Il vous permettra d'exécuter des scripts/programmes tels que vim, dialog, etc., permettant à ces programmes de gérer le contrôle et de revenir à votre script uniquement lorsqu'ils sont terminés.

Si vous utilisez system() ou exec() pour exécuter ces scripts/programmes, cela ne fonctionnera tout simplement pas. Gotcha: Pour quelque raison, vous ne pouvez pas exécuter less avec passthru() en PHP.

+1

Je ne comprends pas ce que vous dites. 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 aura éliminés sélectivement. Bien sûr, un hôte * partagé * est une histoire différente, mais vous n'offrirez pas un environnement * partagé * aux clients estimés non plus, non? – Christian

94

La system() Fonction

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

La exec() Fonction

La fonction du système est très utile et puissant, mais l'un des plus gros problèmes avec c'est que tout le texte résultant du programme passe directement au flux de sortie. Il y aura des situations où vous voudrez 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 de PHP est parfaitement adaptée. Au lieu de dumping automatiquement tout le texte généré par le programme en cours d'exécution dans le flux de sortie, il vous donne l'occasion de mettre ce texte dans un tableau retourné dans le second paramètre à la fonction:

La shell_exec() Fonction

La plupart des programmes que nous avons exécutés jusqu'ici ont été, plus ou moins, de vrais programmes1. Cependant, l'environnement dans lequel les utilisateurs Windows et Unix fonctionnent est en réalité beaucoup plus riche que cela. Les utilisateurs de Windows ont la possibilité d'utiliser le programme Windows Command Prompt, cmd.exe Ce programme s'appelle un shell de commande.

La passthru() Fonction

Une fonction fascinante que PHP offre semblable à ceux que nous avons vu jusqu'à présent est la fonction de relais. Cette fonction, comme les autres, exécute le programme auquel vous le dites. Cependant, il continue à envoyer immédiatement la sortie brute de ce programme au flux de sortie avec lequel PHP travaille actuellement (à savoir soit HTTP dans un scénario de serveur Web, soit le shell dans une version de ligne de commande de PHP).

La fonction proc_open() et popen() fonction

proc_open() est similaire à popen(), mais fournit 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 comment PHP transmet ce descripteur au processus fils. Les pipes seront placées dans 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 devriez le libérer en utilisant proc_close() quand vous en aurez fini.

Crédits: http://php.net/ & & Chipmunkninja (lien n'est pas mentionné parce qu'il ne fonctionne pas, erreur 404)

+4

La vitesse d'exécution de shell_exec est plus rapide que les autres. –

+21

Vous devriez mentionner que vous avez copié votre réponse directement à partir de [ChipmunkNinja] (http://chipmunkninja.com/Program-Execution-in-PHP%[email protected]). – TachyonVortex

+5

@TachyonVortex heureusement, il a copié la réponse verbatim, parce que ChipmunkNinja n'existe plus. – Phileo99

51

La précédente réponse semblait tout être un peu confus ou incomplet, alors voici une table 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 que ce flux la sortie vers le navigateur (ou la sortie de ligne de commande en cas d'exécution à partir d'une ligne de commande).
  • "Can Get Output" 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 et les autres valeurs sont généralement des codes d'erreur.

Autres choses misc à connaître:

  • Le shell_exec() et l'opérateur de faire la même chose contre-apostrophes chose.
  • Il existe également proc_open() et popen() qui vous permettent de lire/écrire de manière interactive des flux avec une commande en cours 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 de sortie $ à exec() pour stocker la sortie, si $ output n'est pas vide, elle ajoutera la nouvelle sortie. Il se peut donc que vous deviez d'abord désactiver ($ output).