Zend Framework uygulamasında kullanıcı yüklenen dosyaları saklamak konusunda ne yapmalı?

2 Cevap php

Ben alışılmış dosya yükleme ve alma (PDF, Word belgeleri, vb) içeren bir web uygulaması oluşturma.

İşte gereksinimleri şunlardır:

  • böylece kullanıcı dosyaları indirebilirsiniz benim görünümü komut onları bağlamak için gerekiyor.
  • dosyaları yapmadınız kullanıcılar için erişilebilir olmamalıdır

Question #1: Where should I store these files?

  1. Dosya sistemi mi?

    • Bu benim public dizininde bir uploads dizini anlamına mı geliyor?
    • Ben de değişiklikler koduna yapıldığında benim uygulamasının yeni bir sürümünü dağıtmak için daha kolay olmasını istiyoruz. Şu anda ben (yani 2009-12-01) geçerli tarih başlıklı bir dizinde benim uygulamayı yüklemek ve başlıklı buna bir sym bağlantı oluşturmak bir süreç var current. Bu bir anda kullanılmakta olan bakılmaksızın, uygulamanın tüm farklı sürümleri arasında paylaşılan olabilir bu yüzden uploads dizin bu dizinin dışında olması gerekir anlamına gelecekti.
  2. Veritabanında?

    • Ben veritabanında dosya içeriğini saklamak ve kullanıcı istekleri onları indirmek için onları kadar hizmet verebilir. Bu yetkili olmayan kullanıcıların güvenliğini benim uygulamada dosyaları tutmak istiyorum, ama bu işi yapmak için bir denetleyici oluşturmak kez ben aynı sonucu elde edebiliriz.
    • Bu sym bağlantıya sahip sorunu çözecek.
    • Ancak, bu (bilgilere ek olarak bir veritabanında dosya içeriği depolamak) kötü bir uygulama olabilir.

Eğer ben yapmalıyım ne düşünüyorsunuz?

Solution:

İşte ben yapıyorum sona ne:

Benim uygulamanın yeni bir sürümünü dağıtmak, ve ben kullanmak istiyorum sürümü için bir sembolik bağ oluşturun:

/server/myapp/releases/2009-12-15
/server/myapp/current -> /server/myapp/releases/2009-12-15

Benim uygulama dizininde üzerinde bir dizin ve benim uygulamada bu dizine bir sembolik bağ oluşturulur:

/server/uploads
/server/myapp/current/application/data/uploads -> /server/uploads

Benim /public/index.php dosyasında bir APPLICATION_UPLOADS_DIR değişken tanımlanmıştır:

// Define path to uploads directory
defined('APPLICATION_UPLOADS_DIR')
    || define('APPLICATION_UPLOADS_DIR', realpath(dirname(__FILE__) . '/../data/uploads'));

Ve yüklemek için dizini ayarlamak benim yükleme formunda bu değişkeni kullanılır:

<?php

class Default_Form_UploadFile extends Zend_Form
{
    public function init()
    {
        //excerpt

        $file = new Zend_Form_Element_File('file');
        $file->setLabel('File to upload:')
            ->setRequired(true)
            ->setDestination(APPLICATION_UPLOADS_DIR);
    }
}

Aynı isimde bir dosya üzerine yazılır edilemez yüzden benim denetleyicisi, ben benzersiz bir şey için dosyayı yeniden adlandırın. Ben bu yüzden daha sonra kullanabilirsiniz benzersiz bir dosya adı, orijinal dosya ve veritabanı mime-tipi kaydedin:

public function uploadAction()
{
    //...excerpt...form has already been validated

    $originalFilename = pathinfo($form->file->getFileName());
    $newFilename = 'file-' . uniqid() . '.' . $originalFilename['extension'];
    $form->file->addFilter('Rename', $newFilename);

    try {
        $form->file->receive();
        //upload complete!

        $file = new Default_Model_File();
        $file->setDisplayFilename($originalFilename['basename'])
            ->setActualFilename($newFilename)
            ->setMimeType($form->file->getMimeType())
            ->setDescription($form->description->getValue());
        $file->save();

        return $this->_helper->FlashMessenger(array('success'=>'The file has been uploaded.'));

    } catch (Exception $exception) {
        //error
    }
}

Dosyaları indirmek için, ben dosyayı alır ve Noginn's SendFile Action Helper yardımıyla kullanıcıya gönderir bir indirme eylemi yarattı.

public function downloadAction()
{
    //user already has permission to download the file
    $this->_helper->layout()->disableLayout(); //won't work if you don't do this
    $file = $this->_getFileFromRequest();
    $location = APPLICATION_UPLOADS_DIR . '/' . $file->getActualFilename();
    $mimeType = $file->getMimeType();
    $filename = $file->getDisplayFilename();
    $this->_helper->sendFile($location, $mimeType, array(
        'disposition' => 'attachment',
        'filename' => $filename
    ));
}

Görünümü komut bir indirme linkini sunmak için, ben dosya kimliği param ile indir eylem onları işaret:

<a href="<?php echo $this->url(array(
    'controller'=>'files',
    'action'=>'download',
    'file'=>$file->id)); ?>"><?php echo $file->displayFilename; ?></a>

İşte bu! Bu yöntemin diğer herhangi bir tavsiye veya eleştirileriniz varsa, cevaplarınız / yorum gönderin.

2 Cevap

Pascal önerilen web kök dışında bir dizine sembolik bağlantılarını iyi bir çözümdür. Eğer dosyalar üzerinde kullanıcı erişim kontrolü çeşit gerekir, özellikle de bunu yapmak için bir yolu, bu dosyaları hizmet için bir php komut dosyası kullanmak olacaktır. Bu web root dışında bazı dizinden dosyayı yükler sonra, bir parametre olarak dosya adını alır ve çıkışları vb indir denetleyici / eylem olabilir. Sonra da tarayıcı onunla ne yapacağını bilir bu yüzden dosyanın kendisinde önce bazı başlıkları göndermek gerekir. Başlıkları indirme iletişim kutusu göstermek için tarayıcı zorlamak için dosya türü belirli ya da sadece genel "octet-stream" ayarlanmış olabilir.