2009-04-09 17 views
258

¿Cuáles son las diferencias?PHP exec() vs sistema() vs passthru()

¿Hay una situación o motivo específico para cada función? Si es así, ¿puedes dar algunos ejemplos de esas situaciones?

PHP.net dice que se utilizan para ejecutar programas externos. see reference Según los ejemplos que veo, no veo ninguna diferencia obvia.

Si tuviera que ejecutar simplemente un script (bash o python), ¿qué función me recomienda usar?

+12

También hay 'proc_open()' y 'popen()', que permiten un mayor grado de control sobre el proceso generado. – Christian

Respuesta

157

Tienen propósitos ligeramente diferentes.

  • exec() es para llamar a un comando del sistema, y ​​quizás tratar con el resultado usted mismo.
  • system() es para ejecutar un comando del sistema e inmediatamente mostrar el resultado, presumiblemente el texto.
  • passthru() es para ejecutar un comando del sistema del cual usted desea el retorno sin procesar, presumiblemente algo binario.

Independientemente, le sugiero que no utilice ninguno de ellos. Todos ellos producen código altamente inportable.

+128

Algunas veces la portabilidad tiene que ser sacrificada por la funcionalidad. Hay algunas cosas que PHP simplemente no puede hacer bien. –

+9

De acuerdo, pero el 95% de las veces las personas quieren usar una llamada shell, las razones son todas incorrectas. – Kalium

+28

@Kalium: ¿pueden dar más detalles sobre su estado de cuenta? solo decir algunas estadísticas de porcentaje vago no me convence. Creo que usar llamadas al sistema para ejecutar scripts es totalmente correcto, siempre y cuando la aplicación no dependa de un conjunto de scripts en el back-end. – codingbear

17

Realmente todo se reduce a la forma en que desea manejar el resultado que el comando puede devolver y si desea que el script PHP espere a que termine o no el programa de llamada.

  • exec ejecuta un comando y pasa la salida a la persona que llama (o lo devuelve de una variable opcional).

  • passthru es similar a la función exec() en que ejecuta un comando. Esta función se debe usar en lugar de exec() o system() cuando la salida del comando Unix es información binaria que se debe pasar directamente al navegador.

  • system ejecuta un programa externo y muestra la salida, pero solo la última línea.

Si necesita ejecutar un comando y tener todos los datos del comando que se pasa directamente de nuevo sin ninguna interferencia, utilice la función passthru().

5

Si está ejecutando su script PHP desde la línea de comandos, passthru() tiene un gran beneficio. Te permitirá ejecutar scripts/programas como vim, dialog, etc., permitiendo que esos programas manejen el control y regresen al script solo cuando terminen.

Si usa system() o exec() para ejecutar esos scripts/programas, simplemente no funcionará.

Gotcha: Por alguna razón, no puede ejecutar less con passthru() en PHP.

+1

No entiendo lo que dices. Puede ejecutar programas desde CLI y (F) CGI (así como mod_php). Puede haber restricciones impuestas por el sistema, como selinux. Pero un sistema bien configurado los desactivará selectivamente. Por supuesto, un host * compartido * es una historia diferente, pero tampoco ofrecerá un ambiente * compartido * a clientes estimados, ¿no? – Christian

94

El system() Función función

El sistema en PHP toma un argumento de cadena con el comando a ejecutar, así como los argumentos usted deseo pasados ​​a ese comando. Esta función ejecuta el comando especificado y vuelca cualquier texto resultante a la secuencia de salida (ya sea la salida HTTP en una situación de servidor web, o la consola si está ejecutando PHP como una herramienta de línea de comandos). El retorno de esta función es la última línea de salida del programa, si emite salida de texto.

La función

El sistema exec() función es muy útil y poderosa, pero uno de los mayores problemas con esto es que todo el texto resultante del programa va directamente a la corriente de salida. Habrá situaciones en las que le gustaría formatear el texto resultante y mostrarlo de alguna manera diferente, o no mostrarlo en absoluto.

Para esto, la función ejecutiva en PHP está perfectamente adaptada. En lugar de vertido de forma automática todo el texto generado por el programa que se ejecuta la secuencia de salida, le da la oportunidad de poner este texto en una matriz devuelta en el segundo parámetro a la función:

El shell_exec() Función

La mayoría de los programas que hemos estado ejecutando hasta ahora han sido, más o menos, programas reales1. Sin embargo, el entorno en el que operan los usuarios de Windows y Unix es en realidad mucho más rico que este. Los usuarios de Windows tienen la opción de usar el programa de símbolo del sistema de Windows, cmd.exe. Este programa se conoce como shell de comando.

El passthru() Función

Una función fascinante que ofrece PHP similares a las que hemos visto hasta ahora es la función de tránsito. Esta función, al igual que las demás, ejecuta el programa que se le indique. Sin embargo, luego procede a enviar inmediatamente la salida sin procesar de este programa al flujo de salida con el que PHP está trabajando actualmente (es decir, HTTP en un escenario de servidor web o el shell en una versión de línea de comando de PHP).

El proc_open() Función y popen() función

proc_open() es similar a popen() pero proporciona un mucho mayor grado de control sobre la ejecución del programa. cmd es el comando que debe ejecutar el shell. descriptorspec es una matriz indexada donde la clave representa el número de descriptor y el valor representa cómo PHP pasará ese descriptor al proceso hijo. las tuberías se establecerán en una matriz indexada de punteros de archivo que corresponden al extremo de PHP de cualquier canal que se cree. El valor de retorno es un recurso que representa el proceso; deberías liberarlo usando proc_close() cuando hayas terminado con él.

Créditos: http://php.net/ & & Chipmunkninja (Enlace no se menciona porque no está funcionando, 404 Error)

+4

La velocidad de ejecución de shell_exec es más rápida que la de otro alternativo. –

+21

Debe mencionar que ha copiado su respuesta directamente de [ChipmunkNinja] (http://chipmunkninja.com/Program-Execution-in-PHP%[email protected]). – TachyonVortex

+5

@TachyonVortex por suerte copió la respuesta textualmente, porque ChipmunkNinja ya no existe. – Phileo99

51

El anterior respondido parecían ser todos un poco confusa o incompleta, por lo que aquí es una tabla de las diferencias. ..

+----------------+-----------------+----------------+----------------+ 
| 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    | 
+----------------+-----------------+----------------+----------------+ 
  • "dispositivo de salida visual" significa que transmite la salida al navegador (o salida de línea de comandos si se ejecuta desde una línea de comandos).
  • "Can Get Output" significa que puede obtener el resultado del comando y asignarlo a una variable de PHP.
  • El "código de salida" es un valor especial devuelto por el comando (también llamado "estado de devolución"). Cero generalmente significa que fue exitoso y otros valores generalmente son códigos de error.

Otras cosas misceláneos a tener en cuenta:

  • El shell_exec() y el operador de comillas invertidas hacer lo mismo.
  • También hay proc_open() y popen() que le permiten leer/escribir secuencias de forma interactiva con un comando de ejecución.
  • Agregue "2> & 1" a la cadena de comandos si también desea capturar/mostrar mensajes de error.
  • Utilice escapeshellcmd() para escapar de los argumentos del comando que pueden contener caracteres problemáticos.
  • Si se pasa una variable de $ salida a exec() para almacenar la salida, si $ output no está vacío, se agregará la nueva salida a la misma. Por lo tanto, es posible que deba desactivar ($ output) primero.