Как сделать загрузку файлов с помощью PHP и Zend Framework?
Я использую 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
}
3 ответа
По умолчанию файлы загружаются во системный временный каталог, что означает, что вы можете:
- использование
move_uploaded_file
переместить файлы куда-нибудь еще, - или настройте каталог, в который Zend Framework должен перемещать файлы; ваш элемент формы должен иметь
setDestination
метод, который может быть использован для этого.
Для второго пункта в руководстве есть пример:
$element = new Zend_Form_Element_File('foo');
$element->setLabel('Upload an image:')
->setDestination('/var/www/upload')
->setValueDisabled(true);
(Но прочитайте эту страницу: есть другая полезная информация)
Если вы переместите файл в общедоступный каталог, любой сможет отправить ссылку на этот файл кому-либо еще, и вы не сможете контролировать, кто имеет доступ к файлу.
Вместо этого вы можете сохранить файл в БД как longblob, а затем использовать Zend Framework, чтобы предоставить пользователям доступ к файлу через контроллер / действие. Это позволит вам обернуть свою собственную аутентификацию и логику прав доступа пользователя в доступ к файлам.
Вам нужно получить файл из каталога /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;
?>
$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);