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

312

Apa perbedaannya?

Apakah ada situasi atau alasan khusus untuk setiap fungsi? Jika ya, dapatkah Anda memberikan beberapa contoh situasi tersebut?

PHP.net mengatakan bahwa mereka digunakan untuk menjalankan program eksternal. lihat referensi Dari contoh yang saya lihat, saya tidak melihat perbedaan yang jelas.

Jika saya hanya menjalankan skrip (bash atau python), fungsi mana yang Anda rekomendasikan untuk saya gunakan?

codingbear
sumber
16
Ada juga proc_open()dan popen(), keduanya memungkinkan tingkat kontrol yang lebih tinggi atas proses melahirkan.
Christian

Jawaban:

195

Mereka memiliki tujuan yang sedikit berbeda.

  • exec() adalah untuk memanggil perintah sistem, dan mungkin berurusan dengan output sendiri.
  • system() adalah untuk menjalankan perintah sistem dan segera menampilkan output - mungkin teks.
  • passthru() adalah untuk mengeksekusi perintah sistem yang Anda inginkan pengembalian mentah - mungkin sesuatu biner.

Bagaimanapun, saya sarankan Anda tidak menggunakan salah satunya. Mereka semua menghasilkan kode yang sangat tidak dapat diport.

Kalium
sumber
147
Terkadang portabilitas harus dikorbankan untuk fungsionalitas. Ada beberapa hal yang tidak bisa dilakukan PHP dengan baik.
Frank Crook
30
@ Kalum: dapatkah Anda menjelaskan lebih lanjut tentang pernyataan Anda? hanya menyatakan beberapa statistik persentase yang tidak jelas tidak meyakinkan saya. Saya percaya bahwa menggunakan pemanggilan sistem untuk mengeksekusi skrip benar-benar baik-baik saja asalkan keseluruhan aplikasi tidak bergantung pada sekumpulan skrip di back-end.
codingbear
46
@Christian izkata@izein:~$ dir -bash: dir: command not found- FreeBSD
Izkata
5
@ OZ_ Saya telah sampai pada situasi di mana saya harus melakukan perhitungan yang sangat mahal. Tidak ada PHP-Module yang tersedia untuk itu. Saya menulis program C saya sendiri dan saya memohonnya dengan passthru (). Terkadang portabilitas bisa menjadi kurang penting daripada hal lain. Tergantung pada proyek.
Paolo
9
Juga, itu adalah kesalahan untuk berpikir bahwa PHP adalah portable selama Anda menghindari exec, system, passthru. Kode PHP bergantung pada lingkungan tempat ia beroperasi, dan banyak bug keamanan karena tidak mempertimbangkan hal ini. Berikut adalah contoh cepat: stackoverflow.com/questions/3003145/…
Pacerier
131

Seperti diambil dari http://php.net/ && Chipmunkninja :

The system () Fungsi

Fungsi sistem dalam PHP mengambil argumen string dengan perintah untuk mengeksekusi serta argumen yang ingin Anda sampaikan ke perintah itu. Fungsi ini mengeksekusi perintah yang ditentukan, dan membuang teks yang dihasilkan ke aliran output (baik output HTTP dalam situasi server web, atau konsol jika Anda menjalankan PHP sebagai alat baris perintah). Kembalinya fungsi ini adalah baris keluaran terakhir dari program, jika ia mengeluarkan keluaran teks.

The exec () Fungsi

Fungsi sistem cukup berguna dan kuat, tetapi salah satu masalah terbesar adalah bahwa semua teks yang dihasilkan dari program langsung menuju ke aliran output. Akan ada situasi di mana Anda mungkin ingin memformat teks yang dihasilkan dan menampilkannya dengan cara yang berbeda, atau tidak menampilkannya sama sekali.

Untuk ini, fungsi exec di PHP diadaptasi dengan sempurna. Alih-alih secara otomatis membuang semua teks yang dihasilkan oleh program yang dieksekusi ke aliran output, itu memberi Anda kesempatan untuk menempatkan teks ini dalam array yang dikembalikan dalam parameter kedua ke fungsi:

The shell_exec () Fungsi

Sebagian besar program yang telah kami jalankan sejauh ini adalah, kurang lebih, program nyata1. Namun, lingkungan di mana pengguna Windows dan Unix beroperasi sebenarnya jauh lebih kaya dari ini. Pengguna Windows memiliki opsi untuk menggunakan program Windows Command Prompt, cmd.exe Program ini dikenal sebagai shell perintah.

The passthru () Fungsi

Satu fungsi menarik yang disediakan PHP mirip dengan yang telah kita lihat sejauh ini adalah fungsi passthru. Fungsi ini, seperti yang lain, menjalankan program yang Anda kirim. Namun, kemudian dilanjutkan untuk segera mengirim output mentah dari program ini ke aliran output dengan mana PHP saat ini bekerja (yaitu HTTP dalam skenario server web, atau shell dalam versi baris perintah PHP).

The proc_open () Fungsi dan popen () function

proc_open () mirip dengan popen () tetapi memberikan tingkat kontrol yang jauh lebih besar terhadap eksekusi program. cmd adalah perintah yang akan dieksekusi oleh shell. descriptorspec adalah array yang diindeks di mana kunci mewakili nomor deskriptor dan nilainya mewakili bagaimana PHP akan meneruskan deskriptor tersebut ke proses anak. pipa akan diatur ke array indeks file pointer yang sesuai dengan akhir PHP dari setiap pipa yang dibuat. Nilai kembali adalah sumber daya yang mewakili proses; Anda harus membebaskannya menggunakan proc_close () saat Anda selesai menggunakannya.

Dinesh Saini
sumber
6
kecepatan eksekusi shell_exec lebih cepat dari alternatif lainnya.
Dinesh Saini
29
Anda harus menyebutkan bahwa Anda telah menyalin jawaban Anda langsung dari ChipmunkNinja .
TachyonVortex
7
@TachyonVortex untungnya dia menyalin jawaban kata demi kata, karena ChipmunkNinja tidak ada lagi.
Phileo99
2
Ada salinan artikel itu di mesin wayback
bagonyi
2
Bagaimana dengan popen dan proc_open?
CMCDragonkai
103

Jawaban sebelumnya sepertinya semuanya sedikit membingungkan atau tidak lengkap, jadi inilah tabel perbedaannya ...

+----------------+-----------------+----------------+----------------+
|    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             |
+----------------+-----------------+----------------+----------------+
  • "Menampilkan Output" berarti streaming output ke browser (atau output baris perintah jika dijalankan dari baris perintah).
  • "Can Get Output" berarti Anda bisa mendapatkan output dari perintah dan menetapkannya ke variabel PHP.
  • "Kode keluar" adalah nilai khusus yang dikembalikan oleh perintah (juga disebut "status pengembalian"). Nol biasanya berarti berhasil, nilai lain biasanya kode kesalahan.

Hal-hal misc lainnya yang perlu diperhatikan:

  • Shell_exec () dan operator backticks melakukan hal yang sama.
  • Ada juga proc_open () dan popen () yang memungkinkan Anda untuk secara interaktif membaca / menulis stream dengan perintah eksekusi.
  • Tambahkan "2> & 1" ke string perintah jika Anda juga ingin menangkap / menampilkan pesan kesalahan.
  • Gunakan escapeshellcmd () untuk keluar dari argumen perintah yang mungkin mengandung karakter bermasalah.
  • Jika melewatkan variabel $ output ke exec () untuk menyimpan output, jika $ output tidak kosong, itu akan menambahkan output baru ke sana. Jadi, Anda mungkin perlu menghapus ($ output) terlebih dahulu.
orrd
sumber
mana yang bisa mengeksekusi file php?
Johnny mengapa
1
@ johny mengapa tidak ada per se - kecuali Anda secara eksplisit memanggil php cli atau semacamnya. Saya kira Anda ingin includedan teman
Hagen von Eitzen
21

Itu benar-benar semua bermuara pada bagaimana Anda ingin menangani output yang mungkin dikembalikan oleh perintah dan apakah Anda ingin skrip PHP Anda menunggu program callee selesai atau tidak.

  • exec mengeksekusi perintah dan meneruskan output ke pemanggil (atau mengembalikannya dalam variabel opsional).

  • passthrumirip dengan exec()fungsi dalam menjalankan perintah. Fungsi ini harus digunakan sebagai pengganti exec()atau system()ketika output dari perintah Unix adalah data biner yang perlu diteruskan langsung kembali ke browser.

  • system mengeksekusi program eksternal dan menampilkan output, tetapi hanya baris terakhir.

Jika Anda perlu menjalankan perintah dan memiliki semua data dari perintah yang dikirimkan langsung kembali tanpa gangguan, gunakan passthru()fungsinya.

Cody Caughlan
sumber
8

Jika Anda menjalankan skrip PHP dari baris perintah, passthru()memiliki satu manfaat besar. Ini akan membiarkan Anda menjalankan skrip / program-program seperti vim, dialog, dll, membiarkan program-program kontrol menangani dan kembali ke naskah Anda hanya ketika mereka selesai.

Jika Anda menggunakan system()atau exec()menjalankan skrip / program tersebut, itu tidak akan berfungsi.

Gotcha: Untuk beberapa alasan, Anda tidak dapat mengeksekusi lessdengan passthru()PHP.

Mat
sumber
1
Saya tidak mengerti apa yang Anda katakan. Anda dapat menjalankan program baik dari CLI dan (F) CGI (serta mod_php). Mungkin ada pembatasan yang diberlakukan oleh sistem, seperti selinux. Tetapi sistem pengaturan yang baik akan menonaktifkannya secara selektif. Tentu saja host bersama adalah cerita yang berbeda, tetapi Anda tidak akan menawarkan lingkungan bersama untuk klien yang terhormat, bukan?
Christian