Ошибка finfo_file(path_to_tmp_file): failed to open stream: No such file or directory

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
azz
Сообщения: 197
Зарегистрирован: 2016.07.06, 17:20

Ошибка finfo_file(path_to_tmp_file): failed to open stream: No such file or directory

Сообщение azz »

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

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

class Banners extends \yii\db\ActiveRecord {
    public $group_id;
    public $bannerImg;

    public function rules() {
        return [
            [['bannerImg'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg, gif'],
            ['name', 'trim'],
            [['product_id', 'name', 'priority', 'bannerImg'], 'required'],
            [['product_id', 'priority', 'disable'], 'integer'],
            [['name'], 'string', 'max' => 200],
            [['product_id'], 'exist', 'skipOnError' => true, 'targetClass' => Products::className(), 'targetAttribute' => ['product_id' => 'id']],
        ];
    }

    public function uploadBanner() {
        if ($this->validate()) {
            $fileName = str_replace('.', '', microtime(true));
            $fullFileName = Yii::getAlias('@app')."/banners/{$fileName}.".$this->bannerImg->extension;

            $this->bannerImg->saveAs($fullFileName);
            $size_v = getimagesize($fullFileName);

            if (empty($size_v[0]) || empty($size_v[1])) {
               @unlink($fullFileName);
                return FALSE;
            }

            $resultObj = new \stdClass();
            $resultObj->filename = $fileName.'.'.$this->bannerImg->extension;
            $resultObj->sizeX = $size_v[0];
            $resultObj->sizeY = $size_v[1];

            return $resultObj;
        }
        else {
            Yii::$app->session->setFlash('error', 'Ошибка загрузки файла');
            return FALSE;
        }
    }
    
........................................................

    public function saveNewBanner($bannerInfo_v) {
        $transaction = Yii::$app->db->beginTransaction();

// в таблице есть поля для имени и размеров
        $this->file_name = $bannerInfo_v->filename;
        $this->size_x = $bannerInfo_v->sizeX;
        $this->size_x = $bannerInfo_v->sizeY;
        
        if ($this->save()) {
                $transaction->commit();

                Yii::$app->session->setFlash('success', 'Баннер добавлен');
                return TRUE;
            }
        }
        else
            $transaction->rollBack();

        Yii::$app->session->setFlash('error', 'Ошибка при добавлении баннера');
        return FALSE;
    }    
контроллер:

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

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

        if ($model->load(Yii::$app->request->post())) {
            $model->bannerImg = \yii\web\UploadedFile::getInstance($model, 'bannerImg');
            $bannerInfo_v = $model->uploadBanner();

            if (!empty($bannerInfo_v)) {
                $model->saveNewBanner($bannerInfo_v);
            }

            return $this->redirect(['view', 'id' => $model->id]);
        } else {
........................................................
вид, думаю не нужен. На выходе при добавлении получаю ошибку
PHP Warning – yii\base\ErrorException
finfo_file(Z:\OpenServer\userdata\temp\php3FF1.tmp): failed to open stream: No such file or directory
Насколько я понял из чтения гугла, ошибка возникает из за того, что сохранение файла через $this->bannerImg->saveAs($fullFileName) нужно делать ПОСЛЕ сохранения модели $this->save(). Но мне надо первым грузить файл, а потом уже сохранять данные в бд. Пробовал, так же по некоторым примерам после присвоения значений полям модели делать $this->bannerImg = NULL, но в этом случае не проходит валидация и мне выдаётся ошибка "Отсутствуют обязательные параметры: id". Какого-то внятного ответа, как поступать в таких случаях я не нашел. Подскажите, что делать и собственно почему так происходит? Я так понимаю это происходит из-за правила валидации 'file', но хотелось бы более полно понять процесс.
NESTA13
Сообщения: 8
Зарегистрирован: 2017.06.08, 14:26

Re: Ошибка finfo_file(path_to_tmp_file): failed to open stream: No such file or directory

Сообщение NESTA13 »

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

- загрузку файла нужно производить вызвав у модели метод saveAs(), без промежуточного обращения к динамическому атрибуту bannerImg модели так:

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

      $this->saveAs($fullFileName);
- у Вас есть уже сформированное название/или путь к файлу, его значение присваиваем свойству bannerImg модели и сохраняем данные
$model->bannerImg = $fullFileName;

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

      $model->save();
Думаю суть ясна и код расписывать нет необходимости.
Александр
Ответить