繁体   English   中英

Yii2文件上传返回UPLOAD_ERR_PARTIAL

[英]Yii2 file upload returns UPLOAD_ERR_PARTIAL

创建新项目时,图像无法上传,但是在更新新创建的项目时,文件已成功上传。 有什么原因吗?
趋势新闻模型

class TrendingNews extends \yii\db\ActiveRecord
{
    const EVENT_ADD_TRENDING_NEWS = 'add-trending-news';
      public $featuredFile;

      public function init() {
         $this->on(self::EVENT_ADD_TRENDING_NEWS, [$this, 'saveToLog']);
      }
    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return 'trending_news';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['headline_text','news_info', 'news_url', 'author', 'published', 'date_added', 'date_modified'], 'required'],
            [['headline_text', 'image_url', 'news_info', 'news_url'], 'string'],
            [['date_added', 'date_modified'], 'safe'],
            [['author'], 'string', 'max' => 20],
            [['published'], 'string', 'max' => 2],
            [['featuredFile'], 'file', 'skipOnEmpty' => false, 'extensions' => 'png, jpg'],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'headline_text' => 'Headline',
            'image_url' => 'Image Url',
            'news_info' => 'Source',
            'news_url' => 'News Url',
            'author' => 'Author',
            'published' => 'Published',
            'date_added' => 'Date Added',
            'date_modified' => 'Date Modified',
            'featuredFile' => 'Featured Image',
        ];
    }

    public function uploadBanner()
    {
        if ($this->validate()) {
           $ymd = date("Ymd");
           $save_path = \Yii::getAlias('@backend') . '/web/uploads/' . $ymd . '/';
            if (!file_exists($save_path)) {
                mkdir($save_path, 0777, true);
            }
            $fileName = "trending_".Yii::$app->security->generateRandomString(20);
            $this->featuredFile->saveAs($save_path . $fileName .'.' . $this->featuredFile->extension);
            $this->image_url = $ymd . '/'. $fileName . '.' . $this->featuredFile->extension;
            return true;
        } else {
            return false;
        }
    }

    public function upload()
    {
        if ($this->validate()) {
           $ymd = date("Ymd");
           $save_path = \Yii::getAlias('@backend') . '/web/uploads/' . $ymd . '/';
            if (!file_exists($save_path)) {
                mkdir($save_path, 0777, true);
            }

            $fileName = Yii::$app->security->generateRandomString(20);

            $this->featuredFile->saveAs($save_path . $fileName .'.' . $this->featuredFile->extension);
            $this->image_url = $ymd . '/'. $fileName . '.' . $this->featuredFile->extension;
            return true;
        } else {
            return false;
        }
    }

    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            if ($this->isNewRecord) {
              $this->date_added = date("YmdHis");
              $this->author =   Yii::$app->user->identity->id;
            } 
            else {
               $this->date_modified = date("YmdHis"); 
            }
            return true;
        }
        else{
            return false;
        }
    }

    public function saveToLog($event)
    {
       //assigning attributes
       // echo 'mail sent to admin using the event';
       $app_log_model = new AppLog();
       $app_log_model->log_time = date("YmdHis");
       $app_log_model->log_activity = 'Added a trending news';
       $app_log_model->user_id = Yii::$app->user->identity->id;
       $app_log_model->device = "1";
       if ($app_log_model->save()) {
           return true;
       } else {
           return $app_log_model->getErrors() ;
       }
    }
}

用法

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

    if ($model->load(Yii::$app->request->post())) {
        $model->featuredFile = UploadedFile::getInstance($model, 'featuredFile');

        if(isset($model->featuredFile)){
            $model->upload();
            $model->save(false);
        } else {
            // file is uploaded successfully
            $model->save();
            //$model->trigger(BlogArticle::EVENT_EDIT_ARTICLE);
        }
        return $this->redirect(['view', 'id' => $model->id]);
    } else {
        return $this->render('create', [
            'model' => $model,
        ]);
    }
}
public function actionUpdate($id)
{
    $model = $this->findModel($id);

    if ($model->load(Yii::$app->request->post())) {
        $model->featuredFile = UploadedFile::getInstance($model, 'featuredFile');
        if(isset($model->featuredFile)){
            $model->upload();
            $model->save(false);
        } else {
            $model->save();
        }
        return $this->redirect(['view', 'id' => $model->id]);
    } else {
        return $this->render('update', [
            'model' => $model,
        ]);
    }
}

应用程序日志显示此

$_FILES = [
    'TrendingNews' => [
        'name' => [
            'featuredFile' => 'another_evento.jpg'
        ]
        'type' => [
            'featuredFile' => ''
        ]
        'tmp_name' => [
            'featuredFile' => ''
        ]
        'error' => [
            'featuredFile' => 3
        ]
        'size' => [
            'featuredFile' => 0
        ]
    ]
]

featuredFile不是数据库字段是否做错了什么? 我正在使用xampp,在实时服务器上尝试过,问题是一样的

如果您必须在插入而不是在更新时要求输入文件,则您做错了,应该为其添加一个方案,以便它仅在添加新记录时要求您提供文件。

其次,您使用相同的ActiveRecord模型,并在其中添加了一个自定义属性以用作文件输入;在upload()函数中,您调用validate() ;如果未通过验证,则返回false,但是同时您没有检查为truefalse在你的控制器动作,并在第二天线你调用$model->save(false)虚假所以在技术上你的脚本将永远亲密的,如果有任何验证错误的用户。

应该在保存记录后上载文件,而不是在保存记录之前上载文件,这样就不会出现任何其他文件上传错误,尽管您希望在insert需要该文件,所以从技术上讲,如果文件没有上载,则不应保存,由于这个原因,我们有用于数据库插入的事务,因此应该使用事务块来保存rcord和文件以及它

如果您有单独的FormModel用于文件上传,则仅应调用validate()方法进行文件上传,否则,应将实例从UploadedFile加载到模型字段,然后调用$model->save() ,该方法将自动验证模型在保存之前,您应该只在上传前检查空文件名,以便在更新任何记录而不提交文件时,原文件应保持原样。

您需要先将验证规则更新为以下内容

/**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['headline_text','news_info', 'news_url', 'author', 'published', 'date_added', 'date_modified'], 'required'],
            [['headline_text', 'image_url', 'news_info', 'news_url'], 'string'],
            [['date_added', 'date_modified'], 'safe'],
            [['author'], 'string', 'max' => 20],
            [['published'], 'string', 'max' => 2],
             [ [ 'featuredFile' ] , 'required' , 'on' => 'insert' ] ,
            [ [ 'featuredFile' ] , 'file' , 'extensions' => 'png, jpg' , 'maxSize' => 200000 , 'tooBig' => 'Limit is 500KB' ] ,
        ];
    }

upload()函数更改为以下内容

 public function upload( $ymd , $fileName ) {
        if ( $this->featuredFile !== null && $this->featuredFile->name !== '' ) {
            $save_path = \Yii::getAlias ( '@backend' ) . '/web/uploads/' . $ymd . '/';
            if ( !file_exists ( $save_path ) ) {
                mkdir ( $save_path , 0777 , true );
            }

            if ( !$this->featuredFile->saveAs ( $save_path . $fileName ) ) {
                $this->addError ( 'featuredFile' , 'File could not be uploaded' );
                throw new \Exception ( 'File upload error' );
            }
        }
    }

然后在模型内部添加另一种方法,以在update上传新文件的情况下删除旧文件

 public function unlinkOldFile( $filename ) {
        if ( $filename !== '' ) {
            $save_path = \Yii::getAlias ( '@backend' ) . '/web/uploads/' . $filename;
            unlink ( $save_path );
        }
    }

之后改变你的createupdate行动,下面,让他们使用transation块进行数据库操作

public function actionCreate() {
    $model = new TrendingNews(['scenario'=>'insert']);

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

        $model->featuredFile = UploadedFile::getInstance ( $model , 'featuredFile' );

        if ( $model->featuredFile !== null ) {
            $ymd = date ( "Ymd" );
            $fileName = Yii::$app->security->generateRandomString ( 20 ) . '.' . $model->featuredFile->extension;
            $model->image_url = $ymd . '/' . $fileName;
        }


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

        try {
            if ( !$model->save () ) {
                throw new \Exception ( 'Error Occoured' );
            }

            $model->upload ( $ymd , $fileName );

            $transaction->commit ();

            return $this->redirect ( [ 'view' , 'id' => $model->id ] );
        } catch ( \Exception $ex ) {
            $transaction->rollBack ();
        }
    }
    return $this->render ( 'create' , [
        'model' => $model ,
        ] );
}

public function actionUpdate( $id ) {
    $model = $this->findModel ( $id );

    if ( $model->load ( Yii::$app->request->post () ) ) {
        $model->featuredFile = UploadedFile::getInstance ( $model , 'featuredFile' );

        //$oldFile = '';
        $oldFile = $model->image_url;

        if ( $model->featuredFile !== null ) {

            $ymd = date ( "Ymd" );

            $fileName = Yii::$app->security->generateRandomString ( 20 ) . '.' . $model->featuredFile->extension;

            $model->image_url = $ymd . '/' . $fileName;

        }

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

        try {
            if ( !$model->save () ) {
                throw new \Exception ( 'Model error' );
            }

            $model->upload ( $ymd , $fileName );

            $model->unlinkOldFile ( $oldFile );

            $transaction->commit ();
            return $this->redirect ( [ 'view' , 'id' => $model->id ] );
        } catch ( Exception $ex ) {
            $transaction->rollBack ();
        }
    }
    return $this->render ( 'update' , [
        'model' => $model ,
        ] );
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM