Exec do PHP () vs system () vs passthru ()

312

Quais são as diferenças?

Existe uma situação ou razão específica para cada função? Se sim, você pode dar alguns exemplos dessas situações?

O PHP.net diz que eles são usados ​​para executar programas externos. veja referência Dos exemplos que vejo, não vejo diferença óbvia.

Se eu fosse simplesmente executar um script (bash ou python), qual função você recomendaria que eu usasse?

codingbear
fonte
16
Há também proc_open()e popen(), ambos os quais permitem um maior grau de controle sobre o processo gerado.
Christian

Respostas:

195

Eles têm finalidades ligeiramente diferentes.

  • exec() é para chamar um comando do sistema e, talvez, lidar com a saída você mesmo.
  • system() é para executar um comando do sistema e exibir imediatamente a saída - presumivelmente texto.
  • passthru() é para executar um comando do sistema do qual você deseja o retorno bruto - presumivelmente algo binário.

Independentemente disso, sugiro que você não use nenhum deles. Todos eles produzem código altamente não portável.

Kalium
fonte
147
Às vezes, a portabilidade precisa ser sacrificada pela funcionalidade. Existem algumas coisas que o PHP simplesmente não pode fazer bem.
Frank Crook
30
@ Kalium: você pode elaborar mais sobre sua declaração? Apenas declarar algumas estatísticas vagas de porcentagem não me convence. Eu acredito que o uso de chamadas do sistema para executar scripts é totalmente bom, desde que todo o aplicativo não dependa de um monte de scripts no back-end.
codingbear
46
@Christian izkata@izein:~$ dir -bash: dir: command not found- FreeBSD
Izkata
5
@OZ_ Cheguei à situação em que tive que fazer cálculos muito caros. Nenhum módulo PHP estava (está) disponível para isso. Eu escrevi meu próprio programa C e o invoco com passthru (). Às vezes, a portabilidade pode ser menos importante do que outras coisas. Depende do projeto.
Paolo
9
Além disso, é uma falácia pensar que o PHP é portátil, desde que você evite exec, system, passthru. O código PHP depende do ambiente em que é executado, e muitos erros de segurança devem-se a não levar isso em consideração. Aqui está um exemplo rápido: stackoverflow.com/questions/3003145/…
Pacerier
131

Como extraído de http://php.net/ && Chipmunkninja :

O sistema () Função

A função do sistema no PHP usa um argumento de cadeia de caracteres com o comando para executar, bem como quaisquer argumentos que você deseja que passem para esse comando. Essa função executa o comando especificado e despeja qualquer texto resultante no fluxo de saída (a saída HTTP em uma situação de servidor da Web ou o console se você estiver executando o PHP como uma ferramenta de linha de comando). O retorno desta função é a última linha de saída do programa, se ela emitir saída de texto.

O exec () Função

A função do sistema é bastante útil e poderosa, mas um dos maiores problemas é que todo o texto resultante do programa vai diretamente para o fluxo de saída. Existem situações em que você pode querer formatar o texto resultante e exibi-lo de uma maneira diferente, ou nem exibi-lo.

Para isso, a função exec no PHP está perfeitamente adaptada. Em vez de descarregar automaticamente todo o texto gerado pelo programa que está sendo executado no fluxo de saída, ele oferece a oportunidade de colocar esse texto em uma matriz retornada no segundo parâmetro da função:

O shell_exec () Função

A maioria dos programas que executamos até agora tem sido, mais ou menos, programas reais1. No entanto, o ambiente em que os usuários do Windows e Unix operam é realmente muito mais rico que isso. Os usuários do Windows têm a opção de usar o programa Windows Command Prompt, cmd.exe. Este programa é conhecido como shell de comando.

O intermediário () Função

Uma função fascinante que o PHP fornece semelhante àquelas que vimos até agora é a função passthru. Esta função, como as outras, executa o programa que você solicita. No entanto, ele passa a enviar imediatamente a saída bruta deste programa para o fluxo de saída com o qual o PHP está trabalhando atualmente (ou seja, HTTP em um cenário de servidor da web ou o shell em uma versão de linha de comando do PHP).

O proc_open () Função e popen () função

proc_open () é semelhante ao popen (), mas fornece um grau muito maior de controle sobre a execução do programa. cmd é o comando a ser executado pelo shell. descriptorspec é uma matriz indexada em que a chave representa o número do descritor e o valor representa como o PHP passará esse descritor para o processo filho. pipes serão configurados para uma matriz indexada de ponteiros de arquivo que correspondem ao final do PHP de quaisquer pipes criados. O valor de retorno é um recurso que representa o processo; você deve liberá-lo usando proc_close () quando terminar.

Dinesh Saini
fonte
6
A velocidade de execução do shell_exec é mais rápida que outra alternativa.
Dinesh Saini
29
Você deve mencionar que copiou sua resposta diretamente do ChipmunkNinja .
TachyonVortex
7
@TachyonVortex, por sorte, ele copiou a resposta literalmente, porque ChipmunkNinja não existe mais.
Phileo99
2
Há uma cópia desse artigo na máquina de wayback
bagonyi
2
E quanto ao popen e proc_open?
precisa saber é o seguinte
103

As respostas anteriores parecem um pouco confusas ou incompletas, então aqui está uma tabela das diferenças ...

+----------------+-----------------+----------------+----------------+
|    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             |
+----------------+-----------------+----------------+----------------+
  • "Exibe saída" significa que transmite a saída para o navegador (ou a saída da linha de comando, se estiver sendo executada em uma linha de comando).
  • "Pode obter saída" significa que você pode obter a saída do comando e atribuí-lo a uma variável PHP.
  • O "código de saída" é um valor especial retornado pelo comando (também chamado de "status de retorno"). Zero geralmente significa que foi bem-sucedido, outros valores são geralmente códigos de erro.

Outras coisas diversas a serem observadas:

  • O shell_exec () e o operador backticks fazem a mesma coisa.
  • Também existem proc_open () e popen () que permitem ler / gravar fluxos interativamente com um comando de execução.
  • Adicione "2> & 1" à sequência de comandos se também desejar capturar / exibir mensagens de erro.
  • Use escapeshellcmd () para escapar dos argumentos do comando que podem conter caracteres problemáticos.
  • Se passar uma variável $ output para exec () para armazenar a saída, se $ output não estiver vazia, ela acrescentará a nova saída. Portanto, você pode precisar desarmar ($ output) primeiro.
orrd
fonte
quais podem executar um arquivo php?
johny why
1
@johnywhy nenhum por si - a menos que você invoque explicitamente o php cli ou algo assim. Eu suponho que você quer includee amigos
Hagen von Eitzen
21

Na verdade, tudo se resume a como você deseja lidar com a saída que o comando pode retornar e se deseja que seu script PHP aguarde o término do programa chamado ou não.

  • exec executa um comando e passa a saída para o chamador (ou a retorna em uma variável opcional).

  • passthrué semelhante à exec()função em que executa um comando. Esta função deve ser usada no lugar de exec()ou system()quando a saída do comando Unix for dados binários que precisam ser passados ​​diretamente de volta ao navegador.

  • system executa um programa externo e exibe a saída, mas apenas a última linha.

Se você precisar executar um comando e receber todos os dados do comando diretamente de volta sem nenhuma interferência, use a passthru()função

Cody Caughlan
fonte
8

Se você estiver executando seu script PHP a partir da linha de comando, terá passthru()um grande benefício. Isso permitirá que você execute scripts / programas como vim, dialogetc, permitindo que esses programas controlem o controle e retornem ao seu script somente quando eles forem concluídos.

Se você usar system()ou exec()executar esses scripts / programas, simplesmente não funcionará.

Gotcha: Por alguma razão, você não pode executar lesscom passthru()no PHP.

Matt
fonte
1
Eu não entendo o que você está dizendo. Você pode executar programas da CLI e (F) CGI (assim como mod_php). Pode haver restrições impostas pelo sistema, como o selinux. Mas um sistema de configuração de poço terá esses seletivamente desativados. É claro que um host compartilhado é uma história diferente, mas você também não oferece um ambiente compartilhado para clientes estimados, não é?
Christian