2009-04-09 34 views
258

Quali sono le differenze?PHP exec() vs system() vs passthru()

Esiste una situazione o un motivo specifico per ciascuna funzione? Se sì, puoi dare alcuni esempi di quelle situazioni?

PHP.net dice che sono utilizzati per eseguire programmi esterni. see reference Dagli esempi che vedo, non vedo alcuna differenza evidente.

Se dovessi semplicemente eseguire uno script (bash o python), quale funzione mi consigliate?

+12

Ci sono anche 'proc_open()' e 'popen()', che consentono entrambi un maggiore grado di controllo sul processo generato. – Christian

risposta

157

Hanno scopi leggermente diversi.

  • exec() è per la chiamata di un comando di sistema e forse per gestire l'output.
  • system() è per l'esecuzione di un comando di sistema e la visualizzazione immediata dell'output - presumibilmente testo.
  • passthru() è per l'esecuzione di un comando di sistema da cui si desidera il ritorno non elaborato - presumibilmente qualcosa di binario.

Indipendentemente da ciò, suggerisco di non usarne nessuno. Tutti producono codice altamente non trasportabile.

+128

A volte la portabilità deve essere sacrificata per la funzionalità. Ci sono alcune cose che PHP non può fare bene. –

+9

Concesso, ma il 95% delle volte le persone vogliono utilizzare una chiamata di shell, i motivi sono tutti sbagliati. – Kalium

+28

@ Kalium: puoi approfondire la tua affermazione? solo affermare alcune statistiche percentuali vaghe non mi convince. Credo che usare le chiamate di sistema per eseguire gli script sia assolutamente soddisfacente finché l'intera applicazione non dipende da una serie di script nel back-end. – codingbear

17

In realtà tutto si riduce a come si desidera gestire l'output che il comando potrebbe restituire e se si desidera che lo script PHP attenda il completamento del programma di chiamata.

  • exec esegue un comando e passa in uscita al chiamante (o ritorna in una variabile opzionale).

  • passthru è simile alla funzione exec() in quanto esegue un comando. Questa funzione deve essere utilizzata al posto di exec() o system() quando l'output dal comando Unix è dati binari che devono essere passati direttamente al browser.

  • system esegue un programma esterno e visualizza l'output, ma solo l'ultima riga.

Se è necessario eseguire un comando ed avere tutti i dati dal comando direttamente senza alcuna interferenza, utilizzare la funzione passthru().

5

Se si sta eseguendo lo script PHP dalla riga di comando, passthru() ha un grande vantaggio. Vi permetterà di eseguire script/programmi come vim, dialog, ecc., Lasciando che questi programmi gestiscano il controllo e ritornino al vostro script solo quando hanno finito.

Se si utilizza system() o exec() per eseguire quegli script/programmi, semplicemente non funzionerà.

Gotcha: per qualche motivo, non è possibile eseguire less con passthru() in PHP.

+1

Non capisco cosa stai dicendo. È possibile eseguire programmi sia da CLI e (F) CGI (che da mod_php). Potrebbero esserci restrizioni imposte dal sistema, come Selinux. Ma un sistema ben impostato avrà quelli selettivamente disattivati. Ovviamente un host * condiviso * è una storia diversa, ma non offrirai un ambiente * condiviso * a clienti stimati, no? – Christian

94

La system() Funzione

Il sistema in PHP prende un argomento stringa con il comando da eseguire, nonché tutti gli argomenti che si desidera passato a quel comando. Questa funzione esegue il comando specificato e scarica qualsiasi testo risultante nel flusso di output (l'output HTTP in una situazione del server Web o la console se si esegue PHP come strumento a riga di comando). Il ritorno di questa funzione è l'ultima riga di output del programma, se emette l'output di testo.

La funzione

Il sistema exec() funzione è molto utile e potente, ma uno dei più grandi problemi con esso è che tutto il testo risultante dal programma va direttamente nel flusso di output. Ci saranno situazioni in cui ti piacerebbe formattare il testo risultante e visualizzarlo in un modo diverso, o non visualizzarlo affatto.

Per questo, la funzione exec in PHP è perfettamente adattata. Invece di pratiche di dumping automaticamente tutto il testo generato dal programma in esecuzione nel flusso di output, ti dà la possibilità di mettere il testo in una matrice restituita nel secondo parametro della funzione:

Il shell_exec() funzione

La maggior parte dei programmi che abbiamo eseguito finora sono stati, più o meno, programmi reali1. Tuttavia, l'ambiente in cui operano gli utenti Windows e Unix è in realtà molto più ricco di questo. Gli utenti di Windows hanno la possibilità di utilizzare il programma del prompt dei comandi di Windows, cmd.exe Questo programma è noto come shell dei comandi.

Il passthru() funzione

Una funzione affascinante che PHP fornisce simili a quelle che abbiamo visto finora è la funzione passante. Questa funzione, come le altre, esegue il programma a cui lo dici. Tuttavia, procede quindi a inviare immediatamente l'output non elaborato da questo programma al flusso di output con cui sta lavorando PHP (vale a dire HTTP in uno scenario di server Web o shell in una versione a riga di comando di PHP).

Il proc_open() Funzione e popen() funzione

proc_open() è simile a popen() ma fornisce un maggior grado di controllo sulla esecuzione del programma. cmd è il comando che deve essere eseguito dalla shell. descriptorspec è un array indicizzato in cui la chiave rappresenta il numero del descrittore e il valore rappresenta il modo in cui PHP passerà tale descrittore al processo figlio. le pipe saranno impostate su una serie indicizzata di puntatori di file che corrispondono alla fine di PHP di qualsiasi pipe che viene creata. Il valore di ritorno è una risorsa che rappresenta il processo; dovresti liberarlo usando proc_close() quando hai finito con esso.

Crediti: http://php.net/ & & Chipmunkninja (Link non è menzionato perché non sta funzionando, 404 errore)

+4

shell_exec la velocità di esecuzione è più veloce di un'altra alternativa. –

+21

Dovresti menzionare che hai copiato la tua risposta direttamente da [ChipmunkNinja] (http://chipmunkninja.com/Program-Execution-in-PHP%[email protected]). – TachyonVortex

+5

@TachyonVortex per fortuna ha copiato la risposta alla lettera, perché ChipmunkNinja non esiste più. – Phileo99

51

Il precedente risposto sembravano essere tutti un po 'di confusione o incompleta, ecco una tabella delle differenze. ..

+----------------+-----------------+----------------+----------------+ 
| 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    | 
+----------------+-----------------+----------------+----------------+ 
  • "visualizza l'uscita" significa che i flussi l'output al browser (output o riga di comando se in esecuzione dalla riga di comando).
  • "Can Get Output" significa che è possibile ottenere l'output del comando e assegnarlo a una variabile PHP.
  • Il "codice di uscita" è un valore speciale restituito dal comando (chiamato anche "stato di ritorno"). Zero di solito significa che ha avuto successo e altri valori sono in genere codici di errore.

Altre cose Varie per essere a conoscenza di:

  • Lo shell_exec() e l'operatore backtick fare la stessa cosa.
  • Esistono anche proc_open() e popen() che consentono di leggere/scrivere in modo interattivo flussi con un comando di esecuzione.
  • Aggiungere "2> & 1" alla stringa di comando se si desidera anche acquisire/visualizzare messaggi di errore.
  • Utilizzare escapeshellcmd() per eseguire l'escape degli argomenti del comando che potrebbero contenere caratteri problematici.
  • Se si passa una variabile $ output a exec() per memorizzare l'output, se $ output non è vuoto, verrà aggiunto il nuovo output ad esso. Quindi potresti aver bisogno di disinserire ($ output) prima.