Загрузить индикатор выполнения с использованием сеанса в PHP 5.4 с помощью codeigniter

В отношении этого урока. Отслеживание загрузки с помощью php. Я хочу, чтобы он работал в Codeigniter. Я не собираюсь начинать работу в CI. Я хочу загружать файлы, а также отслеживать прогресс.

В моем представлении CI

 <?php $arr = array("id"=>"myform");
       echo form_open_multipart("welcome/uploads",$arr); ?>
      <input type="hidden" value="myForm" name="<?php echo ini_get("session.upload_progress.name"); ?>">
      <table>
      <tr>
          <td>file</td>
         <td><input type="file" name="images[]" multiple></td>
     </tr>
     <tr>
         <td>name</td>
         <td><input type="text" name="naam"></td>
    </tr>
    <tr>
        <td></td>
        <td><input type="submit"></td>
    </tr>
</table>
<?php echo form_close(); ?>
<div id="bar_blank">

script

function toggleBarVisibility() {
  var e = document.getElementById("bar_blank");
  e.style.display = (e.style.display == "block") ? "none" : "block";
}

function createRequestObject() {
   var http;
   if (navigator.appName == "Microsoft Internet Explorer") {
       http = new ActiveXObject("Microsoft.XMLHTTP");
   }
   else {
      http = new XMLHttpRequest();
  }
     return http;
}

 function sendRequest() {
   var http = createRequestObject();
   http.open("GET", "<?php echo base_url().'index.php/welcome/progress' ?>");
   http.onreadystatechange = function () { handleResponse(http); };
   http.send(null);
 }

function handleResponse(http) {
   var response;
   if (http.readyState == 4) {
    response = http.responseText;
    document.getElementById("bar_color").style.width = response + "%";
    document.getElementById("status").innerHTML = response + "%";

    if (response < 100) {
        setTimeout("sendRequest()", 1000);
    }
    else {
        toggleBarVisibility();
        document.getElementById("status").innerHTML = "Done.";
      }
   }
}

 function startUpload() {
     toggleBarVisibility();
    setTimeout("sendRequest()", 1000);
 }

 (function () {
      document.getElementById("myForm").onsubmit = startUpload;  //error is here
})();

В соответствии с вышеприведенными учебными пособиями, это в основном php. При отправке запроса формы CI контроллеру dashboard/addRoom и моя страница все равно обновляется. Но в учебных пособиях Form перенаправляет на PHP_SELF (тот же php файл). Я понятия не имею об этом. Пожалуйста, помогите мне.

контроллер

 function progress()
    {
        session_start();

        $key = ini_get("session.upload_progress.prefix") . "myForm";
        if (!empty($_SESSION[$key])) {
            $current = $_SESSION[$key]["bytes_processed"];
            $total = $_SESSION[$key]["content_length"];
            echo $current < $total ? ceil($current / $total * 100) : 100;
        }
        else {
            echo 100;
        }
    }
    public function uploads()
    {
        if(!empty($_FILES['images']['name'][0]))
       {
        //uploadinf file code
       }
    }

Ответы

Ответ 1

Если вы хотите сделать это только с помощью jQuery, я использовал jQuery Form Submit Плагин, который даст вам прогресс и многое другое. Как вы сказали в комментариях, вам не нужен какой-либо плагин, а затем выполните следующие действия и реализуйте, как показано в учебнике.

Предположим, у вас есть панель управления и метод addRoom отображает вашу форму html:

class Dashboard extends CI_Controller {


    function addRoom() {

        // Detect URI: http://example.com/dashboard/addRoom/upload_file
        $upload_req = $this->uri->segment("3");

        if( $upload_req == "upload_file" ) {
            // Do the file upload Actions
        }

        // Generate Form
        $this->load->view("Generate_view");
    }

}

Вид:

<?php 
    $ar = array("class"=>"form-horizontal");
    echo form_open_multipart('dashboard/addRoom/upload_file',$ar);
 ?>
 <input type="text" name="fileName">
 <input type="file" name="upload">
 <input type="submit" value="add">
 <?php echo form_close(); ?>

В этом случае ваша форма все еще находится на том же контроллере и методе, даже вы отправляете или нет.

Обновление:. Согласно обновленному ответу, используйте библиотеки по умолчанию codeigniter для Session и Загрузка файлов. В случае ошибки JS используйте вкладку консоли (Chrome) для отладки ошибки или если вы используете firefox, используйте расширение firebug для отладки Javascript.

Ответ 2

Если вы просто хотите показать ход загрузки, доступно много плагинов, я не знаю, почему вы конкретно упомянули Session в названии.

Здесь - очень приятный и простой плагин, который с легкостью будет работать с любой фреймворк.

Пример кода

<script>
/*jslint unparam: true */
/*global window, $ */
$(function () {
    'use strict';
    // Change this to the location of your server-side upload handler:
    var url = window.location.hostname === 'blueimp.github.io' ?
                '//jquery-file-upload.appspot.com/' : 'server/php/';
    $('#fileupload').fileupload({
        url: url,
        dataType: 'json',
        done: function (e, data) {
            $.each(data.result.files, function (index, file) {
                $('<p/>').text(file.name).appendTo('#files');
            });
        },
        progressall: function (e, data) {
            var progress = parseInt(data.loaded / data.total * 100, 10);
            $('#progress .progress-bar').css(
                'width',
                progress + '%'
            );
        }
    }).prop('disabled', !$.support.fileInput)
        .parent().addClass($.support.fileInput ? undefined : 'disabled');
});
</script>

enter image description here

Ответ 3

Вам не хватает (я не вижу его в вашем коде), что учебник в вашем вопросе объявляет и использует скрытый iframe в атрибуте target формы загрузки, это способ справиться с загрузкой, предотвращая страницу формы для обновления (URL-адрес действия будет загружен в iframe).

google для скрытой загрузки iframe (и в конечном итоге для загрузки formdata, которая в наши дни должна быть лучшим способом обработки загрузок и показывать прогресс с несколькими javascript)

вот старый пример, который использует скрытый iframe Обработка ответов на загрузку файлов Ajax

Обновление

Вы должны изменить код в своем представлении на $arr = array("id"=>"myForm")

В настоящее время я вижу, что это array("id"=>"myform") (все строчные буквы)

getElementById чувствителен к регистру, и вы используете .getElementById("myForm").onsubmit

Когда вы используете какой-либо javascript, и что-то не работает, как ожидалось, браузер javascript-консоли является первым местом для просмотра, вы должны увидеть ошибку, например (chrome):

Uncaught TypeError: Cannot set property 'onsubmit' of null

Это связано с тем, что getElementById не может найти элемент с id myForm и возвращает null, в html/DOM он действительно называется myForm.

Обновление

Итак, я получил то, что работает, вместо контроллера welcome я создал новый контроллер Upload (в верхнем регистре, потому что я использую CI 3 dev, его легко адаптировать к старым версиям), ниже рабочие файлы.

URL будет http://your-host/optional-dir/index.php/upload.

application/controllers/Upload.php:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');

class Upload extends CI_Controller {
    public function index() {
        $this->load->helper(array('form', 'url'));
        $this->load->view('upload');
    }
    function progress() {
        session_start();
        $key = ini_get("session.upload_progress.prefix") . "myForm";
        if (!empty($_SESSION[$key])) {
            $current = $_SESSION[$key]["bytes_processed"];
            $total = $_SESSION[$key]["content_length"];
            echo $current < $total ? ceil($current / $total * 100) : 100;
        }  else {
            echo 100;
        }
    }
    public function uploads() {
        if(!empty($_FILES['images']['name'][0]))  {
            //uploadinf file code
        }
    }
}

application/views/upload.php:

<!DOCTYPE html>
<html>
    <head>
        <title>upload</title>
        <style>
            #bar_blank {
                border: solid 1px #000;
                height: 20px;
                width: 300px;
            }

            #bar_color {
                background-color: #006666;
                height: 20px;
                width: 0px;
            }

            #bar_blank, #hidden_iframe {
                display: none;
            }
        </style>
    </head>
    <body>
        <?php $arr = array("id"=>"myForm", "target"=>"hidden_iframe");
        echo form_open_multipart("upload/uploads",$arr); ?>
        <input type="hidden" value="myForm" name="<?php echo ini_get("session.upload_progress.name"); ?>">
        <table>
            <tr>
                <td>file</td>
                <td><input type="file" name="images[]" multiple></td>
            </tr>
            <tr>
                <td>name</td>
                <td><input type="text" name="naam"></td>
            </tr>
            <tr>
                <td></td>
                <td><input type="submit"></td>
            </tr>
        </table>
        <?php echo form_close(); ?>
        <iframe id="hidden_iframe" name="hidden_iframe" src="about:blank"></iframe>
        <div id="status"></div>
        <div id="bar_blank">
            <div id="bar_color"></div>
        </div>
        <?php include_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'upload.js.php'); ?>
    </body>
</html>

./application/views/upload.js.php:

<script>
function toggleBarVisibility() {
    console.log('toggleBarVisibility');
    var e = document.getElementById("bar_blank");
    e.style.display = (e.style.display == "block") ? "none" : "block";
}

function createRequestObject() {
    console.log('createRequestObject');
    var http;
    if (navigator.appName == "Microsoft Internet Explorer") {
        http = new ActiveXObject("Microsoft.XMLHTTP");
    } else {
        http = new XMLHttpRequest();
    }
    return http;
}

function sendRequest() {
    console.log('sendRequest');
    var http = createRequestObject();
    http.open("GET", "<?php echo base_url().'index.php/upload/progress' ?>");
    http.onreadystatechange = function () { handleResponse(http); };
    http.send(null);
}

function handleResponse(http) {
    console.log('handleResponse');
    var response;
    if (http.readyState == 4) {
        response = http.responseText;
        document.getElementById("bar_color").style.width = response + "%";
        document.getElementById("status").innerHTML = response + "%";

        if (response < 100) {
            setTimeout("sendRequest()", 1000);
        } else {
            toggleBarVisibility();
            document.getElementById("status").innerHTML = "Done.";
        }
    }
}

function startUpload() {
    console.log('startUpload');
    toggleBarVisibility();
    setTimeout("sendRequest()", 1000);
}

(function () {
    console.log('init');
    document.getElementById("myForm").onsubmit = startUpload;  //error is here
})();

</script>

уведомление

Я использую raw include_once для удобства, потому что php base_url используется внутри javascript, возможно, лучше иметь небольшой встроенный javascript в представлении html, который объявляет переменную javascript со значением base_url затем включите статический javascript из каталога ресурсов, как обычно.

Ответ 4

учебник, который я видел, на самом деле вам нужно написать AJAX в своем представлении и вызвать контроллер через ajax, не используя форму отправки с помощью кнопки. так что ваша страница не будет обновлена. внимательно ознакомьтесь с учебным пособием, предоставленным вами ссылкой, и при прокрутке вниз вы увидите javascript, где он отправляет HTTP-запросы через AJAX, например

 function createRequestObject() {
  var http;
  if (navigator.appName == "Microsoft Internet Explorer") {
     http = new ActiveXObject("Microsoft.XMLHTTP");
   }
   else {
    http = new XMLHttpRequest();
  }
   return http;
}

это 1 функция, где она создает XMLHttpRequests для получения ответа от файла, где вы должны получить ответ через XMLHttpRequest с вашего контроллера.

Привет