DbHelp.ru
Маленький Yii блог
Комментарии
Гость: "Пример htaccess файла который избавляет нас от необход...
Гость: Спасибо за серию статей, прошел все 8 уроков.
Гость: А если две капчи (в двух формах) на странице должны быть...
Гость: Спасибо! Хорошее начало - буду читать дальше!
des: вот полная инфа по деревьям http://des1roer.blogspot.ru/2015/03/yii-yii-for-...



Сервер Ultima Online - Forest Wars (от создателя данного блога)

Как загружать файлы с помощью модели?

Рубрика: Перевод Cookbook

Оцените эту статью:

Рейтинг: 0.00 (0)
5 Апр. 2009
Опубликовать в Twitter Написать в Facebook Опубликовать в своем блоге livejournal.com

Yii Framework Blog img http://dbhelp.rucookbook Первым делом необходимо объявить переменную в моделе для хранения имени файла . Также стоит незабыть указать правило валидации (в rules) для нашего поля. Там вы можете задать расширения файлов которые могут быть загружены.

---

class Item extends CActiveRecord
{
    public $image;
    // ... other attributes
 
    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');
                // redirect to success page
            }
        }
        $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/



Если хотите опубликовать этот материал у себя - пожалуйста, разместите ссылку на страницу откуда вы его взяли.
Другие yii статьи:

  1. Спасибо команде разработчиков нашего чудесного фреймворка за отличный подарочек под ёлку - новую версию yii. В релиз включено более 50 ... "Обновляемся, Yii 1.1.13"

  2. Целью данной статьи, является написание проекта «Hello World» на фреймворке Yii, как наиболее простого проекта. Это позволит читателю освоить ... "Проект Hello World с использованием Yii"

  3. Новое сообщение на официальном сайте поддержки Yii информирует нас про утверждение нового дизайна сайта, логотипа и стиля. Как сообщает разработчик фреймворка, ... "Новый Yii дизайн"

[guest] Гость

Было сказано: Суббота, 25 Апрель 2009

Одно не понятно почему CActiveRecord ? разве АР это не для базы данных?

[guest] Гость

Было сказано: Понедельник, 27 Апрель 2009

Предполагается что имя файла который мы загружаем или хотябы путь к нему будет хранится в базе данных. Следовательно за доставерность пришедших с формы данных отвечает модель, отсюда и AP :)

[guest] Константин

Было сказано: Вторник, 28 Апрель 2009

Какая разница - АР или FormModel, в данном случае иллюстрируется валидация поля типа файл и его удобная загрузка средствами Yii.

[adm] zolter

Было сказано: Вторник, 28 Апрель 2009

Да, Константин прав.
В данном случае показано как легко средствами фреймворка проводить и валидацию фаил полей с формы.

romanoza

Было сказано: Четверг, 14 Май 2009

а каким образом можно переименовать файл до save()? что бы сохранить и в базу записать под другим именем?

romanoza

Было сказано: Четверг, 14 Май 2009

сам и отвечаю :)
может быть криво, но сделал так:


$private $_image;

$this->_image=CUploadedFile::getInstance($user,'image');
if($this->_image->name)
$user->image=Gallery::nameImage($this->_image->extensionName);
else
$user->image = NULL;

if ($user->save(false)) {
if($this->_image->name) {
$this->_image->saveAs('images/userfiles/'.Yii::app()->user->id.'/'.$user->image);
}
$this->redirect($redirect);
}

[guest] Максим

Было сказано: Четверг, 14 Май 2009

Спасибо romanoza, хороший вариант!
Также спасибо автору статьи!

[guest] Гость

Было сказано: Суббота, 11 Июль 2009

работаю из-под винды...
выдает ошибку

move_uploaded_file(E:/mowes_portable/site/images/items) [<a href='function.move-uploaded-file'>function.move-uploaded-file</a>]: failed to open stream: Permission denied


что может быть???
папка существует - вставка пути в проводник перекидывает в эту папку

[adm] zolter

Было сказано: Воскресенье, 12 Июль 2009

Странно. Ругается на права доступа к папке. Но в винде у меня такой ошибки некогда не появлялось. Попробуйте удалить текущую папку и создать её по новой через проводник. Поместите в эту папку какойто файл и попробуйте получить к нему доступ через функцию http://ua2.php.net/manual/ru/function.is-writable.php

А какая винда? vista?

[guest] Гость

Было сказано: Суббота, 25 Июль 2009

при сохранении файлов с русскими буквами в названии, сохраняет какую-то ерунду... можно это как-то исправить?

[adm] zolter

Было сказано: Суббота, 25 Июль 2009

Скорее всего это проблемы самой ОС. При сохранении простой кодируйте название файла в md5 к примеру.

[guest] Гость

Было сказано: Суббота, 07 Ноябрь 2009

спасибо за перевод, одно только не ясно, чем отличаются данные метода
$model->save()
$model->image->saveAs()

в частности save() от saveAs()
каждая из них что желает?

вроде как я понял, метод saveAs() сохраняет файл в указанной директории, а вот в методе save() мы не указываем директорю, так смысл от ниё какой?

[adm] zolter

Было сказано: Суббота, 07 Ноябрь 2009

Метод $model->save() сохраняет аттрибуты модели $model в базу данных. При этом работу с самим прикрепленным файлом он не какую не выполняет. Как вы понимаете у нас модель знимается не только загрузкой файла, но и к примеру сохранением другой информации в туже таблицу. К примеру название файла и тп. Поэтому данный метод обновит именно таблицу в БД.

А метод $model->image->saveAs() проводит именно непосредственне сохранение файла на жесткий диск сервера. Без работы с базой данных.

[guest] Гость

Было сказано: Воскресенье, 08 Ноябрь 2009

zolter, спасибо огромное за разъяснение, теперь всё ясно)

[adm] zolter

Было сказано: Воскресенье, 08 Ноябрь 2009

Пожалуйста :)

itsme

Было сказано: Пятница, 04 Декабрь 2009

все понятно кроме одного
в какую таблицу (имя таблицы) модель сохраняется ?

[guest] zolter

Было сказано: Пятница, 04 Декабрь 2009

В модели должен быть метод tableName который указывает, с какой таблицей работает модель:

        public function tableName()
{
return 'art_galery'; // <-ваше имя
}

[guest] Гость

Было сказано: Среда, 27 Январь 2010

Народ, загружать то мы научились, а удалять как? не подскажет никто случайно?

[guest] Гость

Было сказано: Среда, 27 Январь 2010

Может unlink(имя файла)? Или Вы хотите как-то интересней?

[guest] Гость

Было сказано: Четверг, 28 Январь 2010

не мне любой:) главное чтобы удалял, спасибо

[guest] Гость

Было сказано: Вторник, 09 Февраль 2010

хм. у меня такая проблема:
форма с несколькими полями где текстовые значения, а также собственно возможность загрузки файлов в этой же форме.
как достать из формы файл и сохранить его? мне настойчиво пишет что форма пуста если я использую немного переделанный пример приведенный вами. если же я этот пример не использую то имя ффайла в БД сохраняется, а сам файл наверняка удаляется из временных файлов.
как его выловить из временных файлов и скопировать в нужную директорию?

[guest] zolter

Было сказано: Вторник, 09 Февраль 2010

http://ua.php.net/manual/en/function.move-uploaded-file.php

<?php
$uploads_dir = '/uploads';
foreach ($_FILES["pictures"]["error"] as $key => $error) {
if ($error == UPLOAD_ERR_OK) {
$tmp_name = $_FILES["pictures"]["tmp_name"][$key];
$name = $_FILES["pictures"]["name"][$key];
move_uploaded_file($tmp_name, "$uploads_dir/$name");
}
}
?>

[guest] BOLVERIN

Было сказано: Четверг, 11 Февраль 2010

блииииин.. спасибо :) только что-то грузится никак не хочет - нету доступа к папке.

[guest] BOLVERIN

Было сказано: Четверг, 11 Февраль 2010

ужо разобрался абсолютный путь указать надо было

[guest] zolter

Было сказано: Четверг, 11 Февраль 2010

Пожалуйста :)

[guest] Гость

Было сказано: Воскресенье, 25 Апрель 2010

Пацики, чтобы переименовать файл до save() необязательно создавать instance CUploadedFile в $model, можно просто создать допольнительную переменную и генерировать имя уже в $model.


if(isset($_POST['Book'])) {
$model->attributes=$_POST['Book'];
$cover=CUploadedFile::getInstance($model,'cover');
if (isset($cover)) {
//генерация уникального имени файла
$uname=substr(md5(uniqid(rand(), true)), 0, rand(7, 13)).preg_replace('/(^.*)(\.)/','$2',$cover->name);
$model->cover = $uname;
}
if($model->save()) {
// сохранение в БД
if (isset($cover)) {
// сохранение на диск
$cover->saveAs($path.$uname);
$image = Yii::app()->image->load('files/images/'.$uname);
$image->resize(200,100,Image::WIDTH);
$image->save('files/images/thumbs/thumb_'.$uname);
}
$this->redirect(array('view','id'=>$model->id));
}

}

[guest] Joyce

Было сказано: Четверг, 26 Август 2010

В некоторых браузерах код не работает. Файлы просто не грузятся. Дело в том, что одни размещают данные в массив $_POST , а другие в $_FILES. Проверяю тупо print_r(). Кто- нибудь сталкивался с такой проблемой? Заранее пасибо.

[guest] Гость

Было сказано: Четверг, 26 Август 2010

Конкретно на Mac: Safari, Chrome - работает FF-не работает.

[guest] Joyce

Было сказано: Четверг, 26 Август 2010

Yii создаёт скрытые поля для передачи данных файла. Видимо это происходит на этапе submit с помощью JavaScript. Таким образом данные о файле (файлах) пихаются в $_POST. Так кривовато решается проблема с разными браузерами. А так как у меня форма загрузки - Widget, то JavaScript не работает корректно. Кто-нибудь разбирался с процессом?
Не будет ли лучше сделать разборку на сервере и выбирать корректный массив ($_FILES или $_POST соответсвенно).

[adm] zolter

Было сказано: Четверг, 26 Август 2010

Странно не сталкивался с тем что в $_POST кидало, а не в $_FILES.

[guest] Гость

Было сказано: Пятница, 27 Август 2010

To Zolter: Это потому, что не Widget. Написал свой обработчик submit - ActiveForm выкинул оставил CHtml - всё работает. Завтра сделаю зависимость парсинг массивов ($_POST & $_FILES) на сервере, чтобы не использовать JavaScript и дополнительные скрытые поля.

[guest] Гость

Было сказано: Пятница, 27 Август 2010

Согласен!

[guest] Гость

Было сказано: Пятница, 29 Апрель 2011

Никак не ролучается загрузить файл!
CUploadedFile::getInstance - возвращает NULL

[guest] Гость

Было сказано: Пятница, 06 Май 2011


$form=$this->beginWidget('CActiveForm', array(
'id'=>'otzyv-form',
'enableAjaxValidation'=>false,
'htmlOptions' => array('enctype'=>'multipart/form-data'),

[guest] Grigori

Было сказано: Четверг, 09 Июнь 2011

С этим алгоритмом появляется большая проблема, если аплоадится картинка, которую надо проверить на формат и размеры перед записью в базу.
Проверка данных - задача модели, выносить проверку в контроллер так же, как вызов image->saveAs - bad practice.

Лучше вынести вызов ->saveAs() в модель в метод beforeSave(), который вызываются после валидации данных.

Для проверки картинки я написал свой валидатор размеров картинки, он простой, выложу в extensions как руки дойдут.

[guest] Гость

Было сказано: Среда, 14 Декабрь 2011

Извиняюсь что занимаюсь некромантией, но не подскажет кто нибудь:
Как использовать правило для валидации файла если имя картинки должно записывается в другую таблицу (например в Item_Images)

[guest] Гость

Было сказано: Пятница, 06 Апрель 2012

спасибо!

[guest] Гость

Было сказано: Воскресенье, 01 Июль 2012

$model->image=CUploadedFile::getInstance($model,'image');

Если известно уже местоположение файла, как его засунуть за место image?

[guest] Гость

Было сказано: Вторник, 21 Август 2012

public function actionCreate(){

if(isset($_POST['News'])) {

$model->attributes=$_POST['News'];

$cover=CUploadedFile::getInstance($model,'cover');

if (isset($cover)) {

//генерация уникального имени файла

$uname=substr(md5(uniqid(rand(), true)), 0, rand(7, 13)).preg_replace('/(^.*)(\.)/','$2',$cover->name);

$model->cover = $uname;

}

if($model->save()) {

// сохранение в БД

if (isset($cover)) {

// сохранение на диск

$cover->saveAs($path.$uname);

$image = Yii::app()->image->load('images/'.$uname);

$image->resize(200,100,Image::WIDTH);

$image->save('images/thumbs/thumb_'.$uname);

}

#$this->redirect(array('view','id'=>$model->id));

}

$this->render('create', array('model'=>$model));

}
}


Вот сделал под себя. Почему пустая страница? Помогите.

[guest] Гость

Было сказано: Вторник, 25 Сентябрь 2012

Пример на основе этого же урока.
Мне всегда легче разобратся когда есть два примера, повторяющих то же самое с минимальными измениниями, поэтому ставлю свой баян (для бабушек, работающих с yii).
сначала
1. я создала таблицу в базе данных
2. с помощью gii создала model
3. с помощью gii создала CRUD

пример из этой статьи

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');
// redirect to success page
}
}
$this->render('create', array('model'=>$model));
}
}


мои минимальные измениния в файле controllers/HividController.php


public function actionCreate()
{
$model=new Hivid;

// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);

if(isset($_POST['Hivid']))
{
$model->attributes=$_POST['Hivid'];
$model->pathVideo=CUploadedFile::getInstance($model,'pathVideo');


if($model->save())
$model->pathVideo->saveAs(Yii::app()->basePath . '/../images/' . $model->pathVideo);
$this->redirect(array('view','id'=>$model->id));


}

$this->render('create',array(
'model'=>$model,
));
}


мои минимальные изменения в файле models/Hivid.php

class Hivid extends CActiveRecord
{

public $pathVideo;
public function rules()
{
// NOTE: you should only define rules for those attributes that
// will receive user inputs.
return array(
array('pathVideo', 'required'),
array('sport, postTitle', 'length', 'max'=>100),
array('pathVideo', 'length', 'max'=>150),
//array('pathVideo', 'file', 'types'=>'avi, wmv, mpg, mpeg, mov, rm, ram, swf, flv, mp4, txt, jpg, gif, png,'),
array('postCaption', 'safe'),
().
// Please remove those attributes that should not be searched.
array('id, sport, postTitle, postCaption, pathVideo', 'safe', 'on'=>'search'),



);
}

мои минимальные измениния в файле views/hivid/_form.php
<div class="form">

<?php $form=$this->beginWidget('CActiveForm', array(
'id'=>'hivid-form',
'enableAjaxValidation'=>false,
'htmlOptions' => array('enctype' => 'multipart/form-data'),

<div class="row">
<?php echo $form->labelEx($model,'pathVideo'); ?>

<?php echo $form->fileField($model,'pathVideo'); ?>
<?php echo $form->error($model,'pathVideo'); ?>
</div>
<div class="row buttons">
<?php echo CHtml::submitButton($model->isNewRecord ? 'Upload' : 'Save'); ?>
</div>

<?php $this->endWidget(); ?>
)); ?>

[guest] Гость

Было сказано: Понедельник, 20 Январь 2014

не знаю у кого как а у меня все равно не грузится не в локалхост не в веб хостит (( что делать - не знаю

[guest] Гость

Было сказано: Четверг, 14 Август 2014

что это за 'path/to/localFile' ??? Слабо было описать ?
Я туда подставляю '/image/', '/image/'.$s, '/image/мойфайл' и нихнера не сохраняется постоянно выдает ошибки.

Блин столько народа парится над сохранением файла, неужели никто не может предложить один правильный шаблонный вариант ? Ведь задача тупая до ужаса, сохранить файл в папку. Тут никакого yii не надо, оно только мешает.

Оставить комментарий


Код:
Имя: