PHP exec () vs sistem () vs passthru ()


312

Farklılıklar nedir?

Her fonksiyon için belirli bir durum veya sebep var mı? Evet ise, bu durumlardan bazı örnekler verebilir misiniz?

PHP.net bunların harici programları yürütmek için kullanıldığını söylüyor. referansa bakın Gördüğüm örneklerden belirgin bir fark görmüyorum.

Bir komut dosyasını (bash veya python) çalıştırmam gerekirse, hangi işlevi kullanmamı önerirsiniz?


16
Ayrıca proc_open()ve popen()her ikisi de ortaya çıkan süreç üzerinde daha yüksek bir kontrole izin verir.
Christian

Yanıtlar:


195

Biraz farklı amaçları var.

  • exec() bir sistem komutu çağırmak ve belki de çıktıyı kendiniz ele almak içindir.
  • system() bir sistem komutu yürütmek ve çıktıyı hemen görüntülemek içindir - muhtemelen metin.
  • passthru() ham ikili dönüşü istediğiniz bir sistem komutunu yürütmek içindir - muhtemelen ikili bir şey.

Ne olursa olsun, hiçbirini kullanmamanızı öneririm. Hepsi son derece taşınabilir kod üretir.


147
Bazen taşınabilirlik işlevsellik için feda edilmelidir. PHP'nin iyi yapamayacağı bazı şeyler var.
Frank Crook

30
@Kalium: Açıklamanızla ilgili daha fazla ayrıntı verebilir misiniz? sadece bazı belirsiz yüzde istatistiklerini belirtmek beni ikna etmiyor. Komut dosyası yürütmek için sistem çağrılarını kullanmanın, tüm uygulama arka uçta bir grup komut dosyasına bağlı olmadığı sürece tamamen iyi olduğuna inanıyorum.
kodlamaAra

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

5
@OZ_ Çok pahalı hesaplamalar yapmak zorunda kaldığım duruma geldim. Bunun için hiçbir PHP Modülü mevcut değildi. Kendi C programımı yazdım ve passthru () ile çağırıyorum. Bazen taşınabilirlik diğer şeylerden daha az önemli olabilir. Projeye bağlı.
Paolo

9
Ayrıca, bir var safsata kaçınmak olarak PHP sürece taşınabilir olduğunu düşünmek exec, system, passthru. PHP kodu çalıştığı ortama bağımlıdır ve birçok güvenlik hatası bunu dikkate almamaktan kaynaklanmaktadır. İşte kısa bir örnek: stackoverflow.com/questions/3003145/…
Pacerier

131

Http://php.net/ && Chipmunkninja'dan çizildiği gibi :

Sistem () Fonksiyonu

PHP'deki sistem işlevi, yürütme komutuyla birlikte bir dize argümanı ve bu komuta iletilmesini istediğiniz bağımsız değişkenleri alır. Bu işlev belirtilen komutu yürütür ve sonuçta ortaya çıkan metni çıktı akışına (bir web sunucusu durumundaki HTTP çıktısı veya PHP'yi komut satırı aracı olarak çalıştırıyorsanız konsol) döker. Bu işlevin geri dönüşü, metin çıktısı yayınlıyorsa, programın son çıktı satırıdır.

Exec () Fonksiyonu

Sistem işlevi oldukça kullanışlı ve güçlüdür, ancak bununla ilgili en büyük sorunlardan biri, programdan elde edilen tüm metinlerin doğrudan çıkış akışına gitmesidir. Ortaya çıkan metni biçimlendirmek ve farklı bir şekilde görüntülemek veya hiç göstermemek isteyebileceğiniz durumlar olacaktır.

Bunun için PHP'deki exec fonksiyonu mükemmel şekilde uyarlanmıştır. Yürütülen program tarafından oluşturulan tüm metni çıkış akışına otomatik olarak dökmek yerine, bu metni işleve ikinci parametrede döndürülen bir diziye koyma fırsatı verir:

Shell_exec () Fonksiyonu

Şimdiye kadar yürütmekte olduğumuz programların çoğu, az çok gerçek programlar olmuştur1. Ancak, Windows ve Unix kullanıcılarının çalıştığı ortam aslında bundan çok daha zengindir. Windows kullanıcıları cmd.exe Windows Komut İstemi programını kullanma seçeneğine sahiptir. Bu program komut kabuğu olarak bilinir.

Passthru () Fonksiyonu

PHP'nin şimdiye kadar gördüklerimize benzer sağladığı büyüleyici bir işlev passthru işlevidir. Bu işlev, diğerleri gibi, anlattığınız programı yürütür. Ancak, bu programdan derhal ham çıktıyı PHP'nin şu anda çalıştığı çıktı akışına göndermeye devam eder (yani bir web sunucusu senaryosundaki HTTP veya PHP'nin komut satırı sürümündeki kabuk).

Proc_open () Fonksiyonu ve popen () fonksiyonu

proc_open (), popen () işlevine benzer, ancak program yürütme üzerinde çok daha fazla denetim sağlar. cmd kabuk tarafından yürütülecek komuttur. descriptorspec, anahtarın tanımlayıcı numarasını temsil ettiği ve değerin PHP'nin bu tanımlayıcıyı alt sürece nasıl geçireceğini temsil ettiği dizinlenmiş bir dizidir. borular, oluşturulan boruların PHP'nin sonuna karşılık gelen dizinlenmiş bir dosya işaretçisi dizisine ayarlanır. Dönüş değeri, süreci temsil eden bir kaynaktır; işiniz bittiğinde proc_close () kullanarak serbest bırakmalısınız.


6
shell_exec yürütme hızı diğer alternatiflerden daha hızlıdır.
Dinesh Saini

29
Cevabınızı doğrudan ChipmunkNinja'dan kopyaladığınızdan bahsetmelisiniz .
TachyonVortex

7
@TachyonVortex neyse ki cevabı aynen kopyaladı, çünkü ChipmunkNinja artık mevcut değil.
Phileo99

2
Bu makalenin wayback
bagonyi

2
Popen ve proc_open ne olacak?
CMCDragonkai

103

Önceki cevapların hepsi biraz kafa karıştırıcı veya eksik görünüyor, bu yüzden burada farklılıklar tablosu ...

+----------------+-----------------+----------------+----------------+
|    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             |
+----------------+-----------------+----------------+----------------+
  • "Çıktıyı Göster", çıktıyı tarayıcıya (veya bir komut satırından çalıştırılıyorsa komut satırı çıktısını) aktardığı anlamına gelir.
  • "Çıktı Alabilir", komutun çıktısını alıp bir PHP değişkenine atayabileceğiniz anlamına gelir.
  • "Çıkış kodu" komut tarafından döndürülen özel bir değerdir ("dönüş durumu" olarak da bilinir). Sıfır genellikle başarılı olduğu anlamına gelir, diğer değerler genellikle hata kodlarıdır.

Dikkat edilmesi gereken diğer çeşitli şeyler:

  • Shell_exec () ve backticks operatörü de aynı şeyi yapar.
  • Ayrıca proc_open () ve popen (), bir yürütme komutuyla akışları etkileşimli olarak okumanıza / yazmanıza izin verir.
  • Hata mesajlarını da yakalamak / görüntülemek istiyorsanız, komut dizesine "2> & 1" ekleyin.
  • Sorunlu karakterler içerebilecek komut bağımsız değişkenlerinden kaçmak için escapeshellcmd () kullanın.
  • Çıktıyı saklamak için exec () öğesine bir $ çıktı değişkeni iletilirse, $ output boş değilse, yeni çıktıya eklenir. Bu yüzden önce ($ output) ayarını kaldırmanız gerekebilir.

hangileri bir php dosyasını yürütebilir?
johny neden

1
@johnywhy hiçbiri kendi başına - açıkça php cli veya böyle çağırmazsanız. Sanırım istiyorum includeve arkadaşlar
Hagen von Eitzen

21

Gerçekten de komutun geri dönebileceği çıktıyı nasıl ele almak istediğinize ve PHP betiğinizin callee programının bitmesini bekleyip beklemeyeceğine iniyor.

  • exec bir komut yürütür ve çıktıyı arayana iletir (veya isteğe bağlı bir değişkende döndürür).

  • passthruexec()komutu çalıştırdığı işleve benzer . Bu işlev , Unix komutunun çıktısının doğrudan tarayıcıya aktarılması gereken ikili veri olduğu exec()veya bu durumda kullanılması gerekir system().

  • system harici bir program yürütür ve çıktıyı görüntüler, ancak yalnızca son satırı görüntüler.

Bir komut yürütmeniz ve komuttaki tüm verilerin herhangi bir müdahale olmadan doğrudan geri aktarılması gerekiyorsa, passthru()işlevi kullanın .


8

PHP betiğinizi komut satırından çalıştırıyorsanız, passthru()büyük bir yararı vardır. Bu gibi komut dosyaları / programlar yürütmenize izin verir vim,dialog vb, bu programların kolu kontrolünü sağlayarak ve yaptıklarını sadece Senaryonuzun dönüyor.

system()Veya kullanırsanızexec() bu komut / programları çalıştırmak için, sadece iş olmaz.

Gotcha: Nedense PHP lessile çalışamazsınız passthru().


1
Ne dediğini anlamıyorum. Programları hem CLI hem de (F) CGI'dan (mod_php'den) yürütebilirsiniz. Selinux gibi sistem tarafından getirilen kısıtlamalar olabilir. Ancak iyi bir kurulum sistemi bunları seçici olarak kapatacaktır. Tabii ki paylaşılan bir ev sahibi farklı bir hikaye, ama siz değerli müşterilerimize de ortak bir ortam sunmayacaksınız , değil mi?
Christian
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.