Загрузите файл Ajax в yii2

Я хочу загрузить файл с помощью Ajax в yii2 framework, это мой код, но в контроллере «get Instance» возвращает null из-за сериализации данных; Как я могу это сделать?

Это мой контроллер:

<?php public function actionUpdate($id) { $model = Signature::findOne([ 'user_id' => $id, ]); if ($model->load(Yii::$app->request->post())) { $model->file = UploadedFile::getInstance($model, 'file'); $model->file->saveAs('uploads/signature/' . $model->user_id . '.' . $model->file->extension); $model->url = 'uploads/signature/' . $model->user_id . '.' . $model->file->extension; if ($model->save()) { echo 1; } else { echo 0; echo $model->file; } } else { return $this->renderAjax('update', [ 'model' => $model, ]); } } ?> 

Это мой код сценария. Я не могу получить свой файл в контроллере, и он возвращает null

 <?php $script = <<<JS $('form#{$model->formName()}').on('beforeSubmit', function(e) { var \$form = $(this); $.post( \$form.attr("action"), \$form.serialize(), ) .done(function(result){ if(result == 1) { $(document).find('#update_signature_modal').modal('hide'); $.pjax.reload({container:'#branchesGrid'}); //alert(); } else { alert(result); } }).fail(function() { console.log("server error"); }); return false; }); JS; $this->registerJs($script); ?> 

Пожалуйста, сначала обратитесь к

Проблема

Проблема в ajax состоит в том, что детали $_FILES не отправляются в asynchroous-запросе. Когда мы отправляем заполненную форму без запроса ajax и отлаживаем на стороне backend в PHP,

 echo '<pre>'; print_r($_FILES); print_r($_POST); echo '</pre>'; die; 

то мы успешно получаем данные $_FILES и $_POST .

Но когда мы отлаживаем одно и то же в запросе ajax, мы получаем только значения $_POST и получаем $_FILES как NULL . Это привело нас к выводу, что данные $_FILES не отправляются в ajax-запросе нашим вышеуказанным кодом.

Решение

Нам нужно использовать FormData JavaScript.

Что оно делает?

$.ajax простыми словами, он добавляет всю необходимую информацию файла, которая должна быть загружена в параметр data в $.ajax ИЛИ заполнять $_FILES а также все данные $_POST т.е. не ввод файлов, например число строк и т. Д.

В вашем файле просмотра

 <?php $form = ActiveForm::begin(['options' => ['enctype' => 'multipart/form-data']]) ?> <?= $form->field($model, 'title') ?> <?= $form->field($model, 'imageFile')->fileInput() ?> <button type="button" class="btn btn-success subm">Upload</button> <?php ActiveForm::end(); ?> <script> $('.subm').click(function(e){ var formData = new FormData($('form')[0]); console.log(formData); $.ajax({ url: "some_php_file.php", //Server script to process data type: 'POST', // Form data data: formData, beforeSend: beforeSendHandler, // its a function which you have to define success: function(response) { console.log(response); }, error: function(){ alert('ERROR at PHP side!!'); }, //Options to tell jQuery not to process data or worry about content-type. cache: false, contentType: false, processData: false }); }); </script> 

тестирование

Теперь сделайте запрос ajax и отлаживайте в PHP-коде с помощью print_r() как показано выше, вы заметите, что $_FILES не является NULL и содержит все файлы (которые должны быть загружены). И если он установлен, вы можете загрузить с помощью функции move_uploaded_file() funtion

Таким образом, вы загружаете файл через Ajax.

Рефери 1

Рефери 2

Рефери 3

Используйте FormData для получения экземпляра данных типа файла / образа

 $( '#my-form' ) .submit( function( e ) { $.ajax( { url: 'http://host.com/action/', type: 'POST', data: new FormData( this ), processData: false, contentType: false } ); e.preventDefault(); } );