Zend Framework aracılığıyla büyük bir dosya hizmet

6 Cevap php

Bizim uygulamada, kimlik doğrulama kullanıcı vb doğrulamak Kontrolör Eklentiler set üzerinden ele

Ben bir büyük (Video) hizmet etmek istiyorum bunu yapmak için doğrulanmış kullanıcılar-bariz şekilde sadece dosya denetleyicisi () readfile aracılığıyla, ama ben PHP bellek limitini vurur buluyorum - muhtemelen denetleyicisi çıktısının arabelleğe bir yerde.

Nasıl ben sadece bu bir kontrol cihazı için tamponlama kapatabilirsiniz?

EDIT: Teşekkürler, varolan herhangi bir çıktı tamponlama kızarma hakkında tüm yararlı ipuçları - Ben özellikle olsa çerçevesinde bunu yapmanın bir yolu arıyordu sanırım?

6 Cevap

Çıktı dosyası için harici bir komut dosyası kullanarak göz önüne alındığında, ve PHP'nin passthru fonksiyonunu kullanarak tarayıcıya akışı.

Linux tabanlı bir sistemde ise, böyle bir şey deneyebilirsiniz passthru("cat video_file.flv");

Ancak, daha iyi uygulama tamamen (PHP içinde) bu akışı önlemek ve web sunucusu doğrudan akarsu işleyebilir böylece gerçek statik kaynak URL istemci bir 301 HTTP yeniden yönlendirme hazırlamaktır.

İlginç bir sorun ... deneyebilirsin:

// ...
public function largeFileAction()
{
    // this clears all active output buffers
    while (ob_get_level()) {
        ob_end_clean();
    }
    readfile('path/to/large/file');
    exit(); // to prevent further request handling
}
//  ...

Tamam, ben burada tamamen yanlış olabilir, ama (muhtemelen vermeyeceğim hizmet için onlara ihtiyacımız Ben OB çalışmak ZendLayout ve tutucu yardımcıları için etkinleştirilmiş olması gerekir bir yerde okudum düşünüyorum, bu yüzden downloadAction için onları devre dışı bırakmak olurdu zaten dosya).

Böyle bir şey yapmak istediğiniz şeyi elde etmek istiyorsunuz?

class DownloadController
{
    public function downloadAction()
    {
        $this->_helper->layout()->disableLayout();
        $this->_helper->viewRenderer->setNoRender(true);
        // authenticate user if not done elsewhere already
        header( /* ... the usual stuff ... */);
        filepassthru(/* some path outside webroot */);
        exit;
    }
}

Tyson yazdığı gibi, en iyi seçimdir (Eğer sunucu üzerinde tam kontrole varsa), kullanıcıların kimlik bilgilerini doğrulamak ve o dosyayı indirebilirsiniz URL'ye onu (302 geçici yönlendirme) yönlendirmek.

Size zaman belirtilen miktar için geçerli olan bir karma oluşturmak için izin lighttpd.conf ve mod_secdownload kullanırken bu URL'lerin yeniden kullanımını önlemek için.

nginx var X-Accel-Redirect ve Apache mod_xsendfile vardır.

Eğer ayrı hafif bir web sunucusu uygulamak için karar verirseniz (statik dosyaları ve daha hızlı tepki süreleri hizmet ederken esas alt bellek tüketimi) diğer faydaları da vardır.

Bu rota gitmek karar verirseniz sunucuya başka bir IP adresi eklemek ve tek bir IP adresine Apache bağlamak zorunda kalırsınız ya, onlar web sunucuları hem dinlemek diğer diğer sunucu (Nginx lighty) çünkü Bir sürü insan daha yüksek noktalarına erişimi yok çünkü noktası 80. Ve sunucularından biri için port değiştirmek iyi bir fikir değildir.

Başka bir IP adresi ekleyerek bir seçenek değil Eğer port 80 üzerinde nginx yüklemek ve başka portu dinlemesi ve statik tüm dosyaları hizmet edebilir Apache için dinamik istekleri geçmek için bir ters proxy olarak kullanabilirsiniz.

Ben aslında sanmıyorum. Bildiğim kadarıyla php istekte göndermeden önce tüm çıkış tamponlar.

Kullandığınız hafıza limitini artırabilir ini_set()

$handle = fopen('/path/to/file', 'r');
$chunk_size = 8192;

while ($chunk = fread($handle, $chunk_size)) {
    echo $chunk;
    ob_flush();
}

Bu muhtemelen bu doğru başlıklar eklenerek ve gerekirse ikili modda okuma gibi, bazı verdiği gerekir, ancak temel fikir sestir. Ben bir 16 MB PHP bellek limiti, 50 + MB dosya göndermek için bu yöntemi başarıyla kullanmıştır.