如何使用 PHP 和 Zend 框架上传文件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1876577/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to do file uploads with PHP and the Zend Framework?
提问by Andrew
I am using Zend Framework 1.9.6. I think I've got it pretty much figured out except for the end. This is what I have so far:
我正在使用 Zend 框架 1.9.6。我想我已经明白了,除了最后。这是我到目前为止:
Form:
形式:
<?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
));
}
}
Controller:
控制器:
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;
}
}
Now what do I do with the file? It has been uploaded to my /tmpdirectory by default. Obviously that's not where I want to keep it. I want users of my application to be able to download it. So, I'm thinking that means I need to move the uploaded file to the public directory of my application and store the file name in the database so I can display it as a url.
现在我该怎么处理这个文件?已经/tmp默认上传到我的目录了。显然,这不是我想要保留它的地方。我希望我的应用程序的用户能够下载它。所以,我认为这意味着我需要将上传的文件移动到我的应用程序的公共目录并将文件名存储在数据库中,以便我可以将其显示为 url。
Or set this as the upload directory in the first place (though I was running into errors while trying to do that earlier).
或者首先将其设置为上传目录(尽管我之前尝试这样做时遇到了错误)。
Have you worked with uploaded files before? What is the next step I should take?
你以前处理过上传的文件吗?我应该采取的下一步是什么?
Solution:
解决方案:
I decided to put the uploaded files into data/uploads(which is a sym link to a directory outside of my application, in order to make it accessible to all versions of my application).
我决定将上传的文件放入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
}
回答by Pascal MARTIN
By default, files are uploaded to the system temporary directory, which means you'll to either :
默认情况下,文件上传到系统临时目录,这意味着您将:
- use
move_uploaded_fileto move the files somewhere else, - or configure the directory to which Zend Framework should move the files ; your form element should have a
setDestinationmethod that can be used for that.
- 用于
move_uploaded_file将文件移动到其他地方, - 或配置 Zend Framework 应将文件移动到的目录;您的表单元素应该有一个
setDestination可以用于此的方法。
For the second point, there is an example in the manual:
对于第二点,手册中有一个例子:
$element = new Zend_Form_Element_File('foo');
$element->setLabel('Upload an image:')
->setDestination('/var/www/upload')
->setValueDisabled(true);
(But read that page : there are other usefull informations)
(但请阅读该页面:还有其他有用的信息)
回答by Chris Williams
If you were to move the file to a public directory, anyone would be able to send a link to that file to anyone else and you have no control over who has access to the file.
如果您要将文件移动到公共目录,则任何人都可以将指向该文件的链接发送给其他任何人,而您无法控制谁可以访问该文件。
Instead, you could store the file in the DB as a longblob and then use the Zend Framework to provide users access the file through a controller/action. This would let you wrap your own authentication and user permission logic around access to the files.
相反,您可以将文件作为 longblob 存储在数据库中,然后使用 Zend 框架为用户提供通过控制器/操作访问文件的权限。这将允许您围绕对文件的访问来包装自己的身份验证和用户权限逻辑。
You'll need to get the file from the /tmp directory in order to save it to the db:
您需要从 /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
Your action in the controller for viewing would have your authorization logic and then load the row from the db:
您在控制器中查看的操作将具有您的授权逻辑,然后从数据库加载行:
// 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;
Then in the view:
然后在视图中:
<?php
header("Content-Disposition: attachment; filename=".$this->fileName.".".$this->fileNameSuffix);
header('Content-type: ".$this->fileMimeType."');
echo $this->file;
?>
回答by Nanhe Kumar
$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);

