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


312

Quali sono le differenze?

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

PHP.net afferma che sono utilizzati per eseguire programmi esterni. vedi riferimento Dagli esempi che vedo, non vedo alcuna differenza evidente.

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


16
C'è anche proc_open()e popen(), entrambi i quali consentono un maggiore grado di controllo sul processo generato.
Christian,

Risposte:


195

Hanno scopi leggermente diversi.

  • exec() serve per chiamare un comando di sistema e forse per gestire da solo l'output.
  • system() serve per eseguire un comando di sistema e visualizzare immediatamente l'output - presumibilmente testo.
  • passthru() serve per eseguire un comando di sistema da cui desideri il ritorno grezzo - presumibilmente qualcosa di binario.

Indipendentemente da ciò, ti consiglio di non usarne nessuno. Tutti producono codice altamente insostituibile.


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

30
@Kalium: puoi approfondire la tua affermazione? solo affermare alcune vaghe statistiche percentuali non mi convince. Credo che l'utilizzo delle chiamate di sistema per eseguire gli script vada benissimo purché l'intera applicazione non dipenda da un gruppo di script nel back-end.
codingbear

46
@Christian izkata@izein:~$ dir -bash: dir: command not found- FreeBSD
Izkata

5
@OZ_ Sono arrivato alla situazione in cui ho dovuto fare calcoli molto costosi. Nessun modulo PHP era (è) disponibile per questo. Ho scritto il mio programma C e lo invoco con passthru (). A volte la portabilità può essere meno importante di altre cose. Dipende dal progetto.
Paolo,

9
Inoltre, è una fallacia a pensare che PHP è portatile finché si evita exec, system, passthru. Il codice PHP dipende dall'ambiente in cui viene eseguito e molti bug di sicurezza sono dovuti al fatto di non tenerne conto. Ecco un esempio veloce: stackoverflow.com/questions/3003145/...
Pacerier

131

Come tratto da http://php.net/ && Chipmunkninja :

Il sistema di () Funzione

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

Il exec () Funzione

La funzione di sistema è abbastanza utile e potente, ma uno dei maggiori problemi è che tutto il testo risultante dal programma va direttamente al flusso di output. Ci saranno situazioni in cui potresti voler 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 scaricare automaticamente tutto il testo generato dal programma in esecuzione nel flusso di output, ti dà la possibilità di inserire questo testo in un array restituito nel secondo parametro alla funzione:

Lo 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 così. Gli utenti Windows hanno la possibilità di utilizzare il programma Prompt dei comandi di Windows, cmd.exe Questo programma è noto come shell dei comandi.

Il passthru () Funzione

Una funzione affascinante che PHP fornisce in modo simile a quelli che abbiamo visto finora è la funzione passthru. Questa funzione, come le altre, esegue il programma a cui gli hai detto. Tuttavia, procede quindi a inviare immediatamente l'output non elaborato da questo programma al flusso di output con cui PHP sta attualmente lavorando (ovvero HTTP in uno scenario di server Web o shell in una versione a riga di comando di PHP).

La funzione proc_open () e popen () funzione

proc_open () è simile a popen () ma fornisce un grado molto maggiore di controllo sull'esecuzione del programma. cmd è il comando che deve essere eseguito dalla shell. descrittore è 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 verranno impostate su una matrice indicizzata di puntatori di file che corrispondono alla fine di PHP di tutte le pipe create. Il valore restituito è una risorsa che rappresenta il processo; dovresti liberarlo usando proc_close () quando hai finito.


6
la velocità di esecuzione di shell_exec è più veloce di altre alternative.
Dinesh Saini,

29
Dovresti dire che hai copiato la tua risposta direttamente da ChipmunkNinja .
TachyonVortex

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

2
C'è una copia di quell'articolo nella macchina del ritorno: web.archive.org/web/20130809032648/http://chipmunkninja.com/…
bagonyi

2
Che dire di popen e proc_open?
CMCDragonkai,

103

Le risposte precedenti sembrano tutte un po 'confuse o incomplete, quindi 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 output" significa che trasmette l'output al browser (o output della riga di comando se in esecuzione da una riga di comando).
  • "Can Get Output" significa che puoi 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, altri valori sono generalmente codici di errore.

Altre cose varie di cui tenere conto:

  • Shell_exec () e l'operatore backticks fanno la stessa cosa.
  • Esistono anche proc_open () e popen () che consentono di leggere / scrivere in modo interattivo flussi con un comando di esecuzione.
  • Aggiungi "2> & 1" alla stringa di comando se vuoi anche acquisire / visualizzare messaggi di errore.
  • Utilizzare escapeshellcmd () per evitare argomenti di 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 potrebbe essere necessario prima disinserire ($ output).

quali possono eseguire un file php?
johny perché

1
@johnywhy none in sé - a meno che non invochi esplicitamente il php cli o simili. Suppongo tu voglia includee amici
Hagen von Eitzen,

21

Dipende tutto da come si desidera gestire l'output che il comando potrebbe restituire e se si desidera che lo script PHP attenda il completamento del programma chiamato.

  • exec esegue un comando e passa l'output al chiamante (o lo restituisce in una variabile opzionale).

  • passthruè simile alla exec()funzione in quanto esegue un comando. Questa funzione deve essere utilizzata al posto di exec()o system()quando l'output del comando Unix è costituito da 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 e far sì che tutti i dati del comando vengano restituiti direttamente senza alcuna interferenza, utilizzare la passthru()funzione.


8

Se stai eseguendo il tuo script PHP dalla riga di comando, passthru()ha un grande vantaggio. Ti consentirà di eseguire script / programmi come vim, dialogecc., Consentendo a tali programmi di gestire il controllo e tornare allo script solo al termine.

Se usi system()o exec()esegui questi script / programmi, semplicemente non funzionerà.

Gotcha: Per qualche motivo, non è possibile eseguire lesscon passthru()in PHP.


1
Non capisco cosa stai dicendo. È possibile eseguire programmi sia da CLI che (F) CGI (oltre a mod_php). Potrebbero esserci restrizioni imposte dal sistema, come selinux. Ma un sistema ben impostato li disattiverà selettivamente. Naturalmente un host condiviso è una storia diversa, ma non offrirai nemmeno un ambiente condiviso ai clienti stimati, no?
Christian,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.