Загрузить индикатор выполнения с использованием сеанса в 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 с вашего контроллера.
Привет