PHP exec () vs sistema () vs passthru ()

312

¿Cuáles son las diferencias?

¿Existe una situación o razón específica para cada función? En caso afirmativo, ¿puede dar algunos ejemplos de esas situaciones?

PHP.net dice que se utilizan para ejecutar programas externos. ver referencia De los ejemplos que veo, no veo ninguna diferencia obvia.

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

oso codificador
fuente
16
También hay proc_open()y popen(), ambos permiten un mayor grado de control sobre el proceso generado.
Christian

Respuestas:

195

Tienen propósitos ligeramente diferentes.

  • exec() es para llamar a un comando del sistema y tal vez tratar con la salida usted mismo.
  • system() es para ejecutar un comando del sistema e inmediatamente mostrar la salida, presumiblemente texto.
  • passthru() es para ejecutar un comando del sistema del que desea el retorno sin procesar, probablemente algo binario

De todos modos, te sugiero que no uses ninguno de ellos. Todos producen código altamente inportable.

Kalium
fuente
147
A veces la portabilidad tiene que ser sacrificada por la funcionalidad. Hay algunas cosas que PHP simplemente no puede hacer bien.
Frank Crook
30
@ Kalium: ¿puedes dar más detalles sobre tu declaración? Simplemente decir algunas estadísticas de porcentajes vagos no me convence. Creo que el uso de llamadas al sistema para ejecutar scripts está totalmente bien, siempre que la aplicación completa no dependa de un montón de scripts en el back-end.
codingbear
46
@Christian izkata@izein:~$ dir -bash: dir: command not found- FreeBSD
Izkata
55
@OZ_ He llegado a la situación en la que tenía que hacer cálculos muy caros. Ningún módulo PHP estaba (está) disponible para eso. Escribí mi propio programa en C y lo invoco con passthru (). A veces la portabilidad puede ser menos importante que otras cosas. Depende del proyecto.
Paolo
99
Además, es una falacia pensar que PHP es portátil, siempre y cuando se evite exec, system, passthru. El código PHP depende del entorno en el que se ejecuta, y muchos errores de seguridad se deben a que no tienen esto en cuenta. Aquí hay un ejemplo rápido: stackoverflow.com/questions/3003145/…
Pacerier
131

Extraído de http://php.net/ && Chipmunkninja :

El sistema () Función

La función del sistema en PHP toma un argumento de cadena con el comando para ejecutar, así como cualquier argumento que desee pasar a ese comando. Esta función ejecuta el comando especificado y descarga cualquier texto resultante en 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.

El exec () Función

La función del sistema es bastante útil y potente, pero uno de los mayores problemas es que todo el texto resultante del programa va directamente al flujo de salida. Habrá situaciones en las que le gustaría formatear el texto resultante y mostrarlo de una manera diferente, o no mostrarlo en absoluto.

Para esto, la función exec en PHP está perfectamente adaptada. En lugar de volcar automáticamente todo el texto generado por el programa que se ejecuta en la secuencia de salida, le da la oportunidad de colocar este texto en una matriz devuelta en el segundo parámetro de 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 esto. Los usuarios de Windows tienen la opción de usar el programa Símbolo del sistema de Windows, cmd.exe. Este programa se conoce como un shell de comandos.

El tránsito () Función

Una función fascinante que PHP proporciona similar a las que hemos visto hasta ahora es la función passthru. Esta función, como las otras, ejecuta el programa que le indica. Sin embargo, luego procede a enviar inmediatamente la salida sin formato de este programa a la secuencia de salida con la 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 () la función

proc_open () es similar a popen () pero proporciona un 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 secundario. las canalizaciones se establecerán en una matriz indexada de punteros de archivos que corresponden al final de PHP de cualquier canalización que se cree. El valor de retorno es un recurso que representa el proceso; debe liberarlo usando proc_close () cuando haya terminado con él.

Dinesh Saini
fuente
66
La velocidad de ejecución de shell_exec es más rápida que otra alternativa.
Dinesh Saini
29
Debe mencionar que ha copiado su respuesta directamente de ChipmunkNinja .
TachyonVortex
77
@TachyonVortex afortunadamente copió la respuesta literalmente, porque ChipmunkNinja ya no existe.
Phileo99
2
Hay una copia de ese artículo en la máquina wayback: web.archive.org/web/20130809032648/http://chipmunkninja.com/…
bagonyi
2
¿Qué pasa con popen y proc_open?
CMCDragonkai
103

Las respuestas anteriores parecen ser un poco confusas o incompletas, así que aquí hay 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             |
+----------------+-----------------+----------------+----------------+
  • "Muestra la salida" significa que transmite la salida al navegador (o la salida de la línea de comandos si se ejecuta desde una línea de comandos).
  • "Puede obtener salida" significa que puede obtener la salida del comando y asignarla a una variable PHP.
  • El "código de salida" es un valor especial devuelto por el comando (también llamado "estado de retorno"). Cero generalmente significa que fue exitoso, otros valores son generalmente códigos de error.

Otras cosas diversas a tener en cuenta:

  • El shell_exec () y el operador de backticks hacen lo mismo.
  • También hay proc_open () y popen () que le permiten leer / escribir secuencias interactivamente con un comando de ejecución.
  • Agregue "2> & 1" a la cadena de comando si también desea capturar / mostrar mensajes de error.
  • Use escapeshellcmd () para escapar de los argumentos de comando que pueden contener caracteres problemáticos.
  • Si pasa una variable $ output a exec () para almacenar la salida, si $ output no está vacío, se agregará la nueva salida. Por lo tanto, es posible que deba desarmar ($ output) primero.
orrd
fuente
¿cuáles pueden ejecutar un archivo php?
johny por qué
1
@johnywhy none per se, a menos que invoques explícitamente el php cli o similar. Supongo que quieres includey amigos
Hagen von Eitzen
21

Realmente todo se reduce a cómo desea manejar la salida que el comando podría devolver y si desea que su script PHP espere a que el programa llamado termine o no.

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

  • passthrues similar a la exec()función en que ejecuta un comando. Esta función debe usarse en lugar de exec()o system()cuando la salida del comando Unix son datos binarios que deben pasarse directamente al navegador.

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

Si necesita ejecutar un comando y hacer que todos los datos del comando pasen directamente sin ninguna interferencia, use la passthru()función.

Cody Caughlan
fuente
8

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

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

Gotcha: Por alguna razón, no puedes ejecutar lesscon passthru()PHP.

Mate
fuente
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 tendrá desactivados selectivamente. Por supuesto, un host compartido es una historia diferente, pero tampoco ofrecerá un entorno compartido a clientes estimados, ¿no?
Christian