【问题标题】:How to do file uploads with PHP and the Zend Framework?如何使用 PHP 和 Zend 框架进行文件上传?
【发布时间】:2009-12-09 20:16:19
【问题描述】:

我正在使用 Zend Framework 1.9.6。我想我已经明白了,除了结尾。这是我目前所拥有的:

表格:

<?php

class Default_Form_UploadFile extends Zend_Form
{
    public function init()
    {
        $this->setAttrib('enctype', 'multipart/form-data');
        $this->setMethod('post');

        $description = new Zend_Form_Element_Text('description');
        $description->setLabel('Description')
            ->setRequired(true)
            ->addValidator('NotEmpty');
        $this->addElement($description);

        $file = new Zend_Form_Element_File('file');
        $file->setLabel('File to upload:')
            ->setRequired(true)
            ->addValidator('NotEmpty')
            ->addValidator('Count', false, 1);
        $this->addElement($file);

        $this->addElement('submit', 'submit', array(
            'label'    => 'Upload',
            'ignore'   => true
        ));
    }
}

控制器:

public function uploadfileAction()
{
    $form = new Default_Form_UploadFile();
    $form->setAction($this->view->url());

    $request = $this->getRequest();

    if (!$request->isPost()) {
        $this->view->form = $form;
        return;
    }

    if (!$form->isValid($request->getPost())) {
        $this->view->form = $form;
        return;
    }

    try {
        $form->file->receive();
        //upload complete!
        //...what now?
        $location = $form->file->getFileName();
        var_dump($form->file->getFileInfo());
    } catch (Exception $exception) {
        //error uploading file
        $this->view->form = $form;
    }
}

现在我该如何处理该文件?默认已上传到我的/tmp 目录。显然这不是我想保留的地方。我希望我的应用程序的用户能够下载它。所以,我认为这意味着我需要将上传的文件移动到我的应用程序的公共目录并将文件名存储在数据库中,以便我可以将其显示为 url。

或者首先将其设置为上传目录(尽管我之前尝试这样做时遇到了错误)。

您以前处理过上传的文件吗?我应该采取的下一步是什么?

解决方案:

我决定将上传的文件放入data/uploads(这是指向我的应用程序外部目录的符号链接,以便我的应用程序的所有版本都可以访问它)。

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

# /application/forms/UploadFile.php
# Set the file destination on the element in the form
$file = new Zend_Form_Element_File('file');
$file->setDestination(APPLICATION_UPLOADS_DIR);

# /application/controllers/MyController.php
# After the form has been validated...
# Rename the file to something unique so it cannot be overwritten with a file of the same name
$originalFilename = pathinfo($form->file->getFileName());
$newFilename = 'file-' . uniqid() . '.' . $originalFilename['extension'];
$form->file->addFilter('Rename', $newFilename);

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

    # Save a display filename (the original) and the actual filename, so it can be retrieved later
    $file = new Default_Model_File();
    $file->setDisplayFilename($originalFilename['basename'])
        ->setActualFilename($newFilename)
        ->setMimeType($form->file->getMimeType())
        ->setDescription($form->description->getValue());
    $file->save();
} catch (Exception $e) {
    //error
}

【问题讨论】:

    标签: php zend-framework file-upload zend-file


    【解决方案1】:

    默认情况下,文件会上传到系统临时目录,这意味着您可以:

    • 使用move_uploaded_file 将文件移动到其他位置,
    • 或配置 Zend Framework 应该将文件移动到的目录;您的表单元素应该有一个可用于此目的的 setDestination 方法。

    关于第二点,the manual中有一个例子:

    $element = new Zend_Form_Element_File('foo');
    $element->setLabel('Upload an image:')
            ->setDestination('/var/www/upload')
            ->setValueDisabled(true);
    

    (但请阅读该页面:还有其他有用的信息)

    【讨论】:

    • +1 用于在表单元素中配置目标并通过指向手册。
    • 链接现在好像失效了。
    【解决方案2】:

    如果您要将文件移动到公共目录,任何人都可以将该文件的链接发送给其他任何人,而您无法控制谁有权访问该文件。

    相反,您可以将文件作为 longblob 存储在数据库中,然后使用 Zend 框架为用户提供通过控制器/操作访问文件的权限。这将允许您围绕对文件的访问来包装自己的身份验证和用户权限逻辑。

    您需要从 /tmp 目录获取文件才能将其保存到数据库:

    // I think you get the file name and path like this:
    $data = $form->getValues(); // this makes it so you don't have to call receive()
    $fileName = $data->file->tmp_name; // includes path
    $file = file_get_contents($fileName);
    
    // now save it to the database. you can get the mime type and other
    // data about the file from $data->file. Debug or dump $data to see
    // what else is in there
    

    您在控制器中进行查看的操作将具有您的授权逻辑,然后从数据库中加载该行:

    // is user allowed to continue?
    if (!AuthenticationUtil::isAllowed()) {
       $this->_redirect("/error");
    }
    
    // load from db
    $fileRow = FileUtil::getFileFromDb($id); // don't know what your db implementation is
    
    $this->view->fileName = $fileRow->name;
    $this->view->fileNameSuffix = $fileRow->suffix;
    $this->view->fileMimeType = $fileRow->mime_type;
    $this->view->file = $fileRow->file;
    

    然后在视图中:

    <?php
    header("Content-Disposition: attachment; filename=".$this->fileName.".".$this->fileNameSuffix);
    header('Content-type: ".$this->fileMimeType."');
    echo $this->file;
    ?>
    

    【讨论】:

    • 感谢您谈论一旦用户需要下载文件该怎么做。我将执行您提到的下载操作。
    【解决方案3】:
     $this->setAction('/example/upload')->setEnctype('multipart/form-data');
     $photo = new Zend_Form_Element_File('photo');
     $photo->setLabel('Photo:')->setDestination(APPLICATION_PATH ."/../public/tmp/upload"); 
     $this->addElement($photo);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-17
      • 2013-04-22
      • 1970-01-01
      • 1970-01-01
      • 2011-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多