Статья написана для тех, кто уже хоть немного знаком с архитектурой Zend Framework. Если кому-нибудь будет интересно — опишу работу с формами более подробно в отдельной статье.
Для загрузки файлов на сервер с помощью форм в Zend Framework Form есть элемент Zend_Form_Element_File. У него есть фильтр «Rename», который позволяет переименовать закачаный файл. Но есть минус — мы не можем просто указать новое имя для файла, чтобы сохранилось его расширение. Как это сделать? А как быть, если мы используем setMultiFile?
Например, у нас есть следующая форма
addValidator('Size', false, 1024000) — устанавливаем максимальный размер (1000kB)
addValidator('Extension', false, 'jpg,png,gif') — указываем допустимые расширения
Мы специально не указываем setDestination, потому что будем использовать фильтр Rename.
Итак, форма у нас есть, теперь будет принимать файл. Лезем в контроллер и пишем следующее
$file = $form->image->getFileInfo() — берём информацию о закачанном файле image
$ext = split("[/\\.]", $file['image']['name']) — вырезаем расширение из имени файла
$newName = 'newname.'.$ext — задаём новое имя со старым расширением (имя можно сгенерировать, при желании, случайным образом)
$form->image->addFilter('Rename' ... — добавляем фильтр «Rename» к элементу формы image, где передаём новое имя + полный путь к файлу на сервере
$form->image->receive() — переносим файл в нашу папку из временной. Фильтр применяется автоматически
Также у Zend_Form_Element_File есть метод setMultiFile(), который даёт возможность отправить сразу несколько файлов в одном элементе формы. Например:
В данном случае все фильтры и валидаторы будут относиться ко всем файлам сразу. Можно даже указывать минимальное и максимальное количество файлов, которые будут загружаться, с помощью валидатора «Count»
Но есть одно большое «НО». Фильтр «Rename» переименует все файлы «в один». Как быть в такой ситуации? Выход есть. Идём опять в контроллер:
В данном случае мы используем напрямую File_Transfer_Adapter и его метод receive(). Но забудте тогда про валидатор «Count», т.к. он будет считать неверное количество файлов. Так же ошибки выводятся только для одного файла, даже если они были у всех.
Советую, если можно обойтись без setMultiFile(), то лучше его не используйте. Создайте лучше несколько элементов формы File и всё будет работать отлично.
Для загрузки файлов на сервер с помощью форм в Zend Framework Form есть элемент Zend_Form_Element_File. У него есть фильтр «Rename», который позволяет переименовать закачаный файл. Но есть минус — мы не можем просто указать новое имя для файла, чтобы сохранилось его расширение. Как это сделать? А как быть, если мы используем setMultiFile?
Например, у нас есть следующая форма
class Form_Myform extends Zend_Form
{
public function __construct($options = null)
{
parent::__construct($options);
$this->setAttrib('enctype', 'multipart/form-data');
$image = new Zend_Form_Element_File('image');
$image->setLabel('Image:')
->addValidator('Size', false, 1024000)
->addValidator('Extension', false, 'jpg,png,gif');
$submit = new Zend_Form_Element_Submit('go');
$submit->setLabel('Submit');
$elements = array($image, $submit);
$this->addElements($elements);
}
* This source code was highlighted with Source Code Highlighter.
addValidator('Size', false, 1024000) — устанавливаем максимальный размер (1000kB)
addValidator('Extension', false, 'jpg,png,gif') — указываем допустимые расширения
Мы специально не указываем setDestination, потому что будем использовать фильтр Rename.
Итак, форма у нас есть, теперь будет принимать файл. Лезем в контроллер и пишем следующее
$request = $this->getRequest();
$form = new Form_Myform();
if ($request->isPost()) {
if ( $form->isValid( $request->getPost() ) ) {
$file = $form->image->getFileInfo();
$ext = split("[/\\.]", $file['image']['name']);
$newName = 'newname.'.$ext[count($ext)-1];
$form->image->addFilter('Rename', realpath(dirname('.')).
DIRECTORY_SEPARATOR.
'upload'.
DIRECTORY_SEPARATOR.
$newName);
$form->image->receive();
}
}
* This source code was highlighted with Source Code Highlighter.
$file = $form->image->getFileInfo() — берём информацию о закачанном файле image
$ext = split("[/\\.]", $file['image']['name']) — вырезаем расширение из имени файла
$newName = 'newname.'.$ext — задаём новое имя со старым расширением (имя можно сгенерировать, при желании, случайным образом)
$form->image->addFilter('Rename' ... — добавляем фильтр «Rename» к элементу формы image, где передаём новое имя + полный путь к файлу на сервере
$form->image->receive() — переносим файл в нашу папку из временной. Фильтр применяется автоматически
Также у Zend_Form_Element_File есть метод setMultiFile(), который даёт возможность отправить сразу несколько файлов в одном элементе формы. Например:
$image = new Zend_Form_Element_File('image');
$image->setLabel('Image:')
->addValidator('Size', false, 1024000)
->addValidator('Extension', false, 'jpg,png,gif')
->setMultiFile(3);
* This source code was highlighted with Source Code Highlighter.
В данном случае все фильтры и валидаторы будут относиться ко всем файлам сразу. Можно даже указывать минимальное и максимальное количество файлов, которые будут загружаться, с помощью валидатора «Count»
->addValidator('Count', false, array('min' => 1, 'max' => 3))
Но есть одно большое «НО». Фильтр «Rename» переименует все файлы «в один». Как быть в такой ситуации? Выход есть. Идём опять в контроллер:
$request = $this->getRequest();
$form = new Form_Myform();
if ($request->isPost()) {
if ( $form->isValid( $request->getPost() ) ) {
$adapter = $form->image->getTransferAdapter();
$i = 0;
foreach ($adapter->getFileInfo() as $file) {
$ext = split("[/\\.]", $file['name']);
$newName = 'newname'.$i.'.'.$ext[count($ext)-1];
$adapter->addFilter('Rename', realpath(dirname('.')).
DIRECTORY_SEPARATOR.
'upload'.
DIRECTORY_SEPARATOR.
$newName);
$adapter->receive($file['name']);
$i++;
}
}
}
* This source code was highlighted with Source Code Highlighter.
В данном случае мы используем напрямую File_Transfer_Adapter и его метод receive(). Но забудте тогда про валидатор «Count», т.к. он будет считать неверное количество файлов. Так же ошибки выводятся только для одного файла, даже если они были у всех.
Советую, если можно обойтись без setMultiFile(), то лучше его не используйте. Создайте лучше несколько элементов формы File и всё будет работать отлично.