Как загрузить файл используя модель

Обсуждение документации. Переводы Cookbook и авторские рецепты.
Ответить
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Как загрузить файл используя модель

Сообщение pirrat »

Во первых: объявим атрибут (свойство) в модели, которое будет содержать имя файла. Также объявим правила валидации для загружаемого фала, чтобы разрешить загружать файлы определенного типа.

Код: Выделить всё

class Item extends CActiveRecord
{
    public $image;
    // другие свойства
 
    public function rules()
    {
        return array(
            array('image', 'file', 'types'=>'jpg, gif, png'), //устанавливаем правила для файла, позволяющие загружать только картинки!
        );
    }
} 
Затем в контроллере определяем метод, который будет выводить форму, и принимать данные из формы

Код: Выделить всё

class ItemController extends CController
{
    public function actionCreate()
    {
        $model=new Item;
        if(isset($_POST['Item']))
        {
            $model->attributes=$_POST['Item'];
            $model->image=CUploadedFile::getInstance($model,'image');
            if($model->save())
            {
                $model->image->saveAs('path/to/localFile');
                // перенаправляем на страницу, где выводим сообщение об успешной загрузки
            }
        }
        $this->render('create', array('model'=>$model));
    }
} 

И наконец, создаём представление с формой

Код: Выделить всё

<?php echo CHtml::form('','post',array('enctype'=>'multipart/form-data')); ?>
...
<?php echo CHtml::activeFileField($model, 'image'); ?>
...
</form>
оригинал: http://www.yiiframework.com/doc/cookbook/2/

PS: из меня переводчик не очень, по этому перевод вольный!
Хотя статья и не требует особого перевода, но надеюсь кому нибудь пригодится, да и мне нужно потренироваться =)
pirrat
Сообщения: 193
Зарегистрирован: 2009.04.03, 09:41

Re: Как загрузить файл используя модель

Сообщение pirrat »

немного от себя:
при загрузке файла, естественно можно проверять не только тип файла но так же размер, и другие параметры.
вот пример правила которое, разрешает загрузку картинок размером не больше 1МБ

Код: Выделить всё

    public function rules()
    {
        return array(
            array('image', 'file', 'types'=>'jpg, gif, png', 'maxSize' => 1048576), //устанавливаем правила для файла, позволяющие загружать только картинки, размером не больше 1МБ!
        );
    }
 
максимальный и минимальный размер указываем в байтах!

подробнее в api документации http://www.yiiframework.com/doc/api/CFileValidator

PS: как я понял встроенных средств в Yii для работы с изображениями нет, так что надо прикручивать свою библиотеку..
Аватара пользователя
Ozzy
Сообщения: 269
Зарегистрирован: 2009.04.02, 15:09
Откуда: Украина, Одесса

Re: Как загрузить файл используя модель

Сообщение Ozzy »

Мой маленький блог - http://dbhelp.ru
Аватара пользователя
aser
Сообщения: 167
Зарегистрирован: 2009.04.02, 14:25
Откуда: Киев

Re: Как загрузить файл используя модель

Сообщение aser »

Ну от себя могу добавить, на версии PHP 5.1.2, c данным методом возникли трудности

Код: Выделить всё

$item->Image = CUploadedFile::getInstance($photos,'Image');
echo $item->Image;
отдавал Object id #31, для решения этой проблемы я отделил кур от котлет и сделал так:

Код: Выделить всё

$Image = CUploadedFile::getInstance($photos,'Image');
$item->Image = $Image->getName();
echo $item->Image;
Ну и дальше работал там где нужен объект то с объектом, там где нужен просто имя с значением атрибута модели...
к примеру:

Код: Выделить всё

$Image->saveAs( item::getImagePath().$item->Image );
Ну и краткая справка:
Ранее, до PHP 5.2.0, метод __toString вызывался только непосредственно в сочетании с функциями echo() или print(). Начиная с PHP 5.2.0, он вызывается в любом строчном контексте (например, в printf() с модификатором %s), но не в контекстах других типов (например, с %d модификатором). Начиная с PHP 5.2.0, преобразование объекта в строку при отсутствии метода __toString вызывает ошибку E_RECOVERABLE_ERROR.
Аватара пользователя
slavcodev
Сообщения: 3134
Зарегистрирован: 2009.04.02, 21:42
Откуда: Valencia
Контактная информация:

Re: Как загрузить файл используя модель

Сообщение slavcodev »

Поправьте плиз на странице

не

Код: Выделить всё

class Item extends CFormModel
правильно

Код: Выделить всё

class Item extends CActiveRecord
CFormModel не имеет метода save()
Жду Yii 3!
Аватара пользователя
samdark
Администратор
Сообщения: 9489
Зарегистрирован: 2009.04.02, 13:46
Откуда: Воронеж
Контактная информация:

Re: Как загрузить файл используя модель

Сообщение samdark »

Готово.
Аватара пользователя
Palmman
Сообщения: 13
Зарегистрирован: 2009.12.21, 15:44
Откуда: Россия, Москва
Контактная информация:

Re: Как загрузить файл используя модель

Сообщение Palmman »

Спасибо за информацию все замечательно работает. Но, как сделать так, что бы поле image не было обязательным к заполнению?
В моей форме, кроме image, содержится еще куча полей.

Код: Выделить всё

<div class="simple">
<?php echo CHtml::activeLabelEx($model,'name'); ?>
<?php echo CHtml::activeTextField($model,'name',array('size'=>60,'maxlength'=>64)); ?>
</div>
...
<div class="simple">
<?php echo CHtml::activeLabelEx($model, 'image'); ?>
<?php echo CHtml::activeFileField($model, 'image', array('size'=>48,'maxlength'=>50)); ?>
</div>
В случае Update поле image остается пустым, т.к. <input type="file"> заполняется только после нажатия кнопки "обзор"
Аватара пользователя
Palmman
Сообщения: 13
Зарегистрирован: 2009.12.21, 15:44
Откуда: Россия, Москва
Контактная информация:

Re: Как загрузить файл используя модель

Сообщение Palmman »

Palmman писал(а):Спасибо за информацию все замечательно работает. Но, как сделать так, что бы поле image не было обязательным к заполнению?
В моей форме, кроме image, содержится еще куча полей.
В случае Update поле image остается пустым, т.к. <input type="file"> заполняется только после нажатия кнопки "обзор"
Решение проблемы array('image', 'file', 'types'=>'jpg, gif', 'allowEmpty'=>true),

И, что бы два раза не вставать: ругалка при превышении размера файла

Код: Выделить всё

 'maxSize'=>1024 * 1024 * 50, // 50MB
'tooLarge'=>'The file was larger than 50MB. Please upload a smaller file.', 
SpiLLeR
Сообщения: 350
Зарегистрирован: 2009.09.17, 16:47
Откуда: Санкт-Петербург
Контактная информация:

Re: Как загрузить файл используя модель

Сообщение SpiLLeR »

Кто подскажет, как сделать, если человек форму заполнил, отправил файлы и произошла ошибка валидации формы, чтобы ему не пришлось грузить еще раз этот же файл?
Предупрежден - значит вооружен.
devKP.ru
v0id3r
Сообщения: 15
Зарегистрирован: 2010.02.06, 14:03

Re: Как загрузить файл используя модель

Сообщение v0id3r »

SpiLLeR,
ошибки заполняются в контроллере, соответственно beforeValidate - сохранить путь к принятому файлу в сессию пользователя.
сделать проверку: использовать файл из сессии при пустом поле файла в форме.
Dreammaker
Сообщения: 139
Зарегистрирован: 2009.09.02, 16:21
Откуда: Черкассы, Украина

Re: Как загрузить файл используя модель

Сообщение Dreammaker »

кроме того, нужно предусмотреть удаление файла в процессе, ибо может человек передумал грузить файл, или, например, если загрузил несколько файлов и хочет удалить один или несколько из них.

Я тут параллельно симфони смотрю, поэтому к месту и не к месту вспоминаю. У них настройка обработки файлов встроена в генератор админки - там сразу задаешь в yaml куда грузить файл, нужно ли выводить ссылку для удаления, ну и понятно, что после этого генерируется код. Эх.. :)
Ответить