File upload Yii2:使用Kartik/FileInput插件上传图像

File upload Yii2:使用Kartik/FileInput插件上传图像,file-upload,yii2,yii2-advanced-app,File Upload,Yii2,Yii2 Advanced App,我想通过Kartikwidget上传图像。提交表单后,$\u文件['Product']包含有关图像的数据,但getInstance($model,'images')返回null。尝试使用图像[],也为空。 这就是我试图在控制器中var\u dump: public function actionCreate() { $model = new Product(); if ($model->load(Yii::$app->request->

我想通过
Kartik
widget上传图像。提交表单后,
$\u文件['Product']
包含有关图像的数据,但
getInstance($model,'images')
返回
null
。尝试使用
图像[]
,也为空。 这就是我试图在控制器中
var\u dump

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

        if ($model->load(Yii::$app->request->post())) {
            var_dump(UploadedFile::getInstance($model, 'images[]'));die;
这是我的型号
产品

<?php

namespace app\models;

use backend\models\CActiveRecord;
use Yii;
use omgdef\multilingual\MultilingualQuery;
use omgdef\multilingual\MultilingualBehavior;
use yii\web\UploadedFile;

/**
 * This is the model class for table "product".
 *
 * @property int $id
 * @property int $category_id
 * @property int $quantity
 * @property double $price
 * @property int $sort
 *
 * @property Productlang[] $productlangs
 */
class Product extends CActiveRecord
{
    public $images;

    public static function find()
    {
        return new MultilingualQuery(get_called_class());
    }

    public function behaviors()
    {
        $allLanguages = [];
        foreach (Yii::$app->params['languages'] as $title => $language) {
            $allLanguages[$title] = $language;
        }

        return [
            'ml' => [
                'class' => MultilingualBehavior::className(),
                'languages' => $allLanguages,
                //'languageField' => 'language',
                //'localizedPrefix' => '',
                //'requireTranslations' => false',
                //'dynamicLangClass' => true',
                //'langClassName' => PostLang::className(), // or namespace/for/a/class/PostLang
                'defaultLanguage' => Yii::$app->params['languageDefault'],
                'langForeignKey' => 'product_id',
                'tableName' => "{{%productLang}}",
                'attributes' => [
                    'title',
                    'description',
                    'meta_title',
                    'meta_desc',
                    'url'
                ]
            ],
        ];
    }
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'product';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        $string = $this->multilingualFields(['description', 'url']);
        $string_59 = $this->multilingualFields(['meta_title']);
        $string_255 = $this->multilingualFields(['meta_desc', 'title']);

        $string[] = 'description';
        $string[] = 'url';
        $string_59[] = 'meta_title';
        $string_255[] = 'meta_desc';
        $string_255[] = 'title';

        return [
            [['quantity', 'price', 'title', 'meta_title', 'meta_desc'], 'required'],
            [['category_id', 'quantity', 'sort'], 'integer'],
            [$string, 'string'],
            [$string_59, 'string', 'max' => 59],
            [$string_255, 'string', 'max' => 255],
            [['price'], 'number'],
            ['images', 'file']
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'category_id' => 'Category ID',
            'quantity' => 'Quantity',
            'price' => 'Price',
            'sort' => 'Sort',
        ];
    }

    public function upload()
    {
        if ($this->validate()) {
            foreach ($this->image as $file) {
                $file->saveAs(\Yii::getAlias("@images") . "/products/" . $this->id . "_" . $this->image->baseName . '.' . $this->image->extension);
            }
            return true;
        } else {
            return false;
        }
    }
}
完全控制器操作:

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

        if ($model->load(Yii::$app->request->post())) {

            foreach (Yii::$app->params['languages'] as $language){
                if(Yii::$app->params['languageDefault'] != $language){

                    $title_lang = "title_$language";
                    $model->$title_lang = Yii::$app->request->post('Product')["title_$language"];

                    $description_lang = "description_$language";
                    $model->$description_lang = Yii::$app->request->post('Product')["description_$language"];

                    $meta_title_lang = "meta_title_$language";
                    $model->$meta_title_lang = Yii::$app->request->post('Product')["meta_title_$language"];

                    $meta_desc_lang = "meta_desc_$language";
                    $model->$meta_desc_lang = Yii::$app->request->post('Product')["meta_desc_$language"];

                }
            }

            if($model->save()){

                $model = $this->findModel($model->id, true);

                //Make urls
                foreach (Yii::$app->params['languages'] as $language) {
                    if (Yii::$app->params['languageDefault'] != $language) {
                        $url_lang = "url_$language";
                        $title_lang = "title_$language";
                        $model->$url_lang = $model->constructURL(
                            $model->$title_lang,
                            $model->id
                        );
                    }else{
                        $model->url = $model->constructURL(
                            $model->title,
                            $model->id
                        );
                    }
                }

                //Upload Images
                $model->images = UploadedFile::getInstance($model, 'images');
                if (!($model->upload())) {
                    Yii::$app->session->setFlash('error',  Yii::t('app', 'Some problem with the image uploading occure!'));
                    return $this->redirect(['create']);
                }


                if($model->update() !== false){
                    return $this->redirect(['view', 'id' => $model->id]);
                }else{
                    Yii::$app->session->setFlash('error',  Yii::t('app', 'Something went wrong. Please, try again later!'));
                    return $this->redirect(['create']);
                }
            }
        }

        return $this->render('create', [
            'model' => $model,
        ]);
    }

如果您试图上载单个图像,则应该从ActiveForm字段声明的输入字段名和模型规则中删除
[]

单个文件
多个文件
对于多个文件,您需要为字段添加
'options'=>['multiple'=>true]
,并将属性名称更改为
images[]

<?= $form->field($model, 'images[]')->widget(FileInput::class, [
                'showMessage' => true,
                'pluginOptions' => [
                        'showCaption' => false ,
                        'showRemove' => false ,
                        'showUpload' => false ,
                        'showPreview' => false ,
                        'browseClass' => 'btn btn-success btn-block' ,
                        'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
                        'browseLabel' => 'Select Profile Image'
                    ] ,
                    'options' => ['accept' => 'image/*' ,'multiple'=>true] ,
            ]) ?>
我个人更喜欢使用单独的模型来上传文件,而不是使用ActiveRecord模型

注意:使用多文件上载时,还可以在模型规则中指定
'maxFiles'=>1000
,以限制要上载的文件数

编辑

为了对代码进行故障排除,您应该注释掉控制器中的
操作创建
,并替换为我在下面添加的操作

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

    if ( $model->load ( Yii::$app->request->post () ) ) {

        foreach ( Yii::$app->params['languages'] as $language ) {
            if ( Yii::$app->params['languageDefault'] != $language ) {

                $title_lang = "title_$language";
                $model->$title_lang = Yii::$app->request->post ( 'Product' )["title_$language"];

                $description_lang = "description_$language";
                $model->$description_lang = Yii::$app->request->post ( 'Product' )["description_$language"];

                $meta_title_lang = "meta_title_$language";
                $model->$meta_title_lang = Yii::$app->request->post ( 'Product' )["meta_title_$language"];

                $meta_desc_lang = "meta_desc_$language";
                $model->$meta_desc_lang = Yii::$app->request->post ( 'Product' )["meta_desc_$language"];
            }
        }

        $transaction = Yii::$app->db->beginTransaction ();

        try {
            if ( !$model->save () ) {
                throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
            }

            //Make urls
            foreach ( Yii::$app->params['languages'] as $language ) {
                if ( Yii::$app->params['languageDefault'] != $language ) {
                    $url_lang = "url_$language";
                    $title_lang = "title_$language";
                    $model->$url_lang = $model->constructURL (
                            $model->$title_lang , $model->id
                    );
                } else {
                    $model->url = $model->constructURL (
                            $model->title , $model->id
                    );
                }
            }

            //save the new urls
            if ( !$model->save () ) {
                throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
            }

            //Upload Images
            $model->images = UploadedFile::getInstances ( $model , 'images' );
            $model->upload ();

            //commit the transatction to save the record in the table
            $transaction->commit ();

            Yii::$app->session->setFlash ( 'success' , 'The model saved successfully.' );
            return $this->redirect ( [ 'view' , 'id' => $model->id ] );
        } catch ( \Exception $ex ) {
            $transaction->rollBack ();
            Yii::$app->session->setFlash ( 'error' , Yii::t ( 'app' , $ex->getMessage () ) );
        }
    }

    return $this->render ( 'create' , [
                'model' => $model ,
            ] );
}
对于ActiveForm,请确保您的输入与以下内容匹配

$form->field($model, 'images[]')->widget(FileInput::class, [
            'showMessage' => true,
            'pluginOptions' => [
                    'showCaption' => false ,
                    'showRemove' => false ,
                    'showUpload' => false ,
                    'showPreview' => false ,
                    'browseClass' => 'btn btn-success btn-block' ,
                    'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
                    'browseLabel' => 'Select Profile Image'
                ] ,
                'options' => ['accept' => 'image/*','multiple'=>true ] ,
]) ;
$form->field($model,'images[])->widget(FileInput::class[
'showMessage'=>true,
“插件操作”=>[
'showCaption'=>false,
“showRemove”=>false,
'showUpload'=>false,
'showPreview'=>false,
'browseClass'=>'btn btn成功btn块',
'browseIcon'=>'',
'browseLabel'=>'选择配置文件图像'
] ,
'选项'=>['accept'=>'image/*','multiple'=>true],
]) ;

是的,它适用于单个图像。但是当我尝试使用多个时,它不会上传它们
getInstance
返回null(然后我使用括号:))。我为他们准备了一张表格-
product\u image
和一个模型
ProductImage
。我猜在整个测试之后,我忘了修复
images
属性。但在修复后,它不再适用于多个。返回null。仍然
null
。我真的很困惑,因为我不是第一次这么做。。模型属性
public$images=[];表单字段
;控制器
上传文件::getInstance($model,'images')
。还尝试了上面的
$form->field
,只是为了以防万一。它可能是Yii2版本的东西吗?我的是
2.0.14
,我现在工作的是Yii2
2.0.6
::它应该是
UploadedFile::getInstances($model,'images')
而不是
getInstance
,如果这里写的不是打字错误,我现在正在
2.0.15.1
上测试它,奇怪的是
NULL
,您是否可以为操作添加完整的代码,而不是将属性声明为数组,只需像
public$images
@tomatomovc那样声明它就可以通过运行composer update来更新框架,我在本地机器上测试了这些设置,它们工作正常。我刚刚注意到您有一个
上传
功能,并且您正在尝试迭代
foreach($this->image as$file){
既然你定义的属性是
images
@TomaTomov,你能添加你拥有的完整控制器/动作吗。你为什么在动作中保存图像两次?在哪里?这
if($model->save())
部分?我想这不会保存图像。在save方法上,我没有保存它,因为我没有调用
upload()
方法,对吗?
//保存图像$model->images=UploadedFile::getInstance($model,'images');如果(!empty($model->images)){$model->upload();}
就在
$model->Save()之后
然后
//上传图像$model->Images=UploadedFile::getInstance($model,'Images');if(!($model->Upload()){Yii::$app->session->setFlash('error',Yii::t('app',图像上传出现一些问题!');返回$this->重定向(['create'])}
//将url设置为“我的坏”
之后…第一个是不必要的。您首先调用
if($model->save())
,然后在检查中再次覆盖
$model->url
$model->$url\u lang
,然后再次调用
$model->update()
<?= $form->field($model, 'images[]')->widget(FileInput::class, [
                'showMessage' => true,
                'pluginOptions' => [
                        'showCaption' => false ,
                        'showRemove' => false ,
                        'showUpload' => false ,
                        'showPreview' => false ,
                        'browseClass' => 'btn btn-success btn-block' ,
                        'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
                        'browseLabel' => 'Select Profile Image'
                    ] ,
                    'options' => ['accept' => 'image/*' ,'multiple'=>true] ,
            ]) ?>
UploadedFile::getInstances($model, 'images');
public function actionCreate() {
    $model = new Product();

    if ( $model->load ( Yii::$app->request->post () ) ) {

        foreach ( Yii::$app->params['languages'] as $language ) {
            if ( Yii::$app->params['languageDefault'] != $language ) {

                $title_lang = "title_$language";
                $model->$title_lang = Yii::$app->request->post ( 'Product' )["title_$language"];

                $description_lang = "description_$language";
                $model->$description_lang = Yii::$app->request->post ( 'Product' )["description_$language"];

                $meta_title_lang = "meta_title_$language";
                $model->$meta_title_lang = Yii::$app->request->post ( 'Product' )["meta_title_$language"];

                $meta_desc_lang = "meta_desc_$language";
                $model->$meta_desc_lang = Yii::$app->request->post ( 'Product' )["meta_desc_$language"];
            }
        }

        $transaction = Yii::$app->db->beginTransaction ();

        try {
            if ( !$model->save () ) {
                throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
            }

            //Make urls
            foreach ( Yii::$app->params['languages'] as $language ) {
                if ( Yii::$app->params['languageDefault'] != $language ) {
                    $url_lang = "url_$language";
                    $title_lang = "title_$language";
                    $model->$url_lang = $model->constructURL (
                            $model->$title_lang , $model->id
                    );
                } else {
                    $model->url = $model->constructURL (
                            $model->title , $model->id
                    );
                }
            }

            //save the new urls
            if ( !$model->save () ) {
                throw new \Exception ( implode ( "<br />" , \yii\helpers\ArrayHelper::getColumn ( $model->errors , 0 , false ) ) );
            }

            //Upload Images
            $model->images = UploadedFile::getInstances ( $model , 'images' );
            $model->upload ();

            //commit the transatction to save the record in the table
            $transaction->commit ();

            Yii::$app->session->setFlash ( 'success' , 'The model saved successfully.' );
            return $this->redirect ( [ 'view' , 'id' => $model->id ] );
        } catch ( \Exception $ex ) {
            $transaction->rollBack ();
            Yii::$app->session->setFlash ( 'error' , Yii::t ( 'app' , $ex->getMessage () ) );
        }
    }

    return $this->render ( 'create' , [
                'model' => $model ,
            ] );
}
public function upload() {
    $skipped = [];
    foreach ( $this->images as $file ) {
        if ( !$file->saveAs ( \Yii::getAlias ( "@images" ) . "/products/" . $this->id . "_" . $this->image->baseName . '.' . $this->image->extension ) ) {
            $skipped[] = "File " . $file->baseName . " was not saved.";
        }
    }
    if ( !empty ( $skipped ) ) {
        Yii::$app->session->setFlash ( 'error' , implode ( "<br>" , $skipped ) );
    }
}
$form->field($model, 'images[]')->widget(FileInput::class, [
            'showMessage' => true,
            'pluginOptions' => [
                    'showCaption' => false ,
                    'showRemove' => false ,
                    'showUpload' => false ,
                    'showPreview' => false ,
                    'browseClass' => 'btn btn-success btn-block' ,
                    'browseIcon' => '<i class="glyphicon glyphicon-camera"></i> ' ,
                    'browseLabel' => 'Select Profile Image'
                ] ,
                'options' => ['accept' => 'image/*','multiple'=>true ] ,
]) ;