filesystyem görüntüyü görüntülemek için file_get_contents veya readfile

5 Cevap php

file_get_contents veya readfile - Herkes iyi PHP işlevi dosya sisteminde depolanan bir görüntü görüntüleme için ne tavsiye edebilirsiniz. Biz bu yüzden biz hala bir PHP dosyası üzerinden görüntüleri aramak için ve dosya sistemine doğrudan bağlantı veremezsiniz ihtiyaç veritabanında saklanan görüntüme geçiş vardır. Ben iki fonksiyonları tavsiye insanları gördüm ama readfile kullanarak yöneldiğine değilim. Bu konuda herhangi bir giriş seviniriz.

5 Cevap

Bir sürü gerektiren - sen (..., filigran ekleme, yeniden boyutlandırma) görüntüleri işlemek için gerek yoksa readfile() will be the best choice as it writes the file directly to the output buffer. file_get_contents() yerine belleğe dosyayı okuyacak büyük dosyalarla bellek.

Bu gibi scriptler yazarken dikkate caching almak için emin olun!

Görüntü sonraki sayfa ziyaretinizde yeniden talep olduğunda statik bir görüntü veren bir web sunucusu istemcisi ile müzakere yapacak ve sunucu istemci tarafında görüntünün önbelleğe alınmış kopyası hala geçerli olduğunu belirlerse, görüntü olmayacak dağıtılamaz.

Naif komut dosyası, bu müzakere yapmaz yana, görüntü size gerekli olandan çok daha fazla bant genişliği maliyeti, her sayfa isteği üzerine müşteriye aktarılan edilecektir.

Bunun için üç mekanizma bulunmaktadır. Ben daha önce bunu yapmak zorunda kalmamıştım gibi, optimum senaryo yazmaya nasıl tam olarak söyleyemem ve ben farklı önbelleğe alma başlıkları birbirleri ile nasıl emin ve hangi HTTP sürümü değilim, ama bu araştırma için teşvik daha fazla.

Bildiğim üç mekanizma:

Expires (HTTP/1.0)

En basit bir. Bu başlık görüntü kesinlikle zamanında verilen ana kadar geçerli olacak müşteri söyler. İstemci, bu süre geçinceye kadar, hatta komut dosyası için bir istek yapmayacağım, bu nedenle uygun bu ayar size web uygulaması sunucu ve görüntü yükleme süresi için (bazı) CPU döngülerini kaydedebilirsiniz.

Eğer bu uygulama tamamen bağlıdır ayarlamanız gerekir nasıl; görüntüleri hızla ya da nadiren değişiyor? Eğer müşteriye yolladım süre dolmadan görüntü değiştirirse, istemci yeni görüntü görmez.

Örnek:

header("Expires: " . gmdate('D, d-M-Y H:i:s \G\M\T', time() + 60)); // Valid for a minute

(Not: Bitiş HTTP/1.1 in Cache-Control yerini almış gibi görünüyor)

If-Modified-Since (HTTP/1.1)

Zaten bir resmin kopyasını ve kopya tarihleri ​​ne zaman notlar varsa, bir HTTP/1.1 istemci bu başlığı gönderebilirsiniz. Görüntünün güncel sürümü bir önceki ya da sonraki bir zamanda değiştirildi eğer sonra veritabanında belirleyebilirsiniz. Istemci sürümü hala doğru olup olmadığını, sadece (böylece görüntü aktarmak zorunda önleyen) bir "304 Değişmedi" yanıtı göndermek ve çıkın.

Örnek:

$cache_time   = parse_browsers_date_time_format($_SERVER["IF-MODIFIED-SINCE"]);
$actual_time  = get_current_resource_time_from_db();

if ($actual_time <= $cache_time) {
    header("HTTP/1.1 304 Not Modified");
    die;
}

// ... Produce and output resource here

(Not: sadece istemciler aslında gönderebilir If-Modified-Since Ayrıca orijinal yanıt Last-Modified göndermek eğer ben bu konuda emin değilim, kendiniz için araştırma.).

ETag/If-None-Match (HTTP/1.1)

Bu yöntem, If-Modified-Since müzakere benzer, ancak içeriği değişip değişmediğini görmek için yerine kez bu görüntünün bir karma kullanır. Aşağıdaki gibi çalışır: sunucu görüntü için bazı karmasını hesaplar ve bu karma resim ETag başlığında istenen ilk defa gönderir.

Sonraki istekleri üzerine, sunucu geri isteği alanında karma göndereceğiz If-None-Match. Müşteri karma görüntünün geçerli karma olarak aynı ise, görüntü arasında değişti değildi ve script basitçe, "Değişmedi 304" göndererek yeterli olabilir.

ETAG'ları aslında yan etkileri ile müşteri istekleri eşzamanlılık sorunları önlemek (örneğin, POST ve PUT) için kullanılan ve bir karma hesaplarken pahalı bir işlem olduğu için amaçlanan gibi görünüyor bu yana, bence If-Modified-Since yaklaşım olacaktır Çoğu dosya-hizmet uygulamaları için daha uygun.

Ben böyle bir şey yapardı:

header('Content-type: image/jpeg');
readfile('something.jpg');

Bir dosyayı okur ve dosyadan okunan bayt sayısını veya bir hata yanlış dönen çıkış tamponuna yazar gibi readfile() bu amaç için daha kullanışlı görünüyor.

I should use fpassthru Using fopen you can handle errors more precisely.

PS: dosya sistemindeki direkt çıkışı savunmasız değildir, emin olun!

file_get_contents() bir dizeye bir dosyanın içeriğini okumak için tercih edilen yoldur. Performansını artırmak için işletim sistemi tarafından destekleniyorsa bellek haritalama teknikleri kullanacağız. Ama bu bir yana, ben daha ne olduğunu bilmiyorum. Sen büyük bir dosya file_get_contents() ile daha iyi performans vermek olmadığını görmek için deneyebilirsiniz, ama ben ağ trafiği sunucular dosya IO çok daha büyük bir sorundur bekliyoruz. ve readfile() header() olarak content-type geçerek dosyasını indirmek için kullanılır.