Я хочу загрузить файл с помощью 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(); } );