Я пытаюсь проверить ход загрузки файлов. Я использую структуру Kohana, которая имеет класс Session, но для процесса загрузки я использую собственные PHP-сессии. Я session_start()
в bootstrap.php Kohana, что означает, что session_start()
будет вызываться при каждом запросе страницы.
После $.ajax()
1 секунду, а затем начал вызывать файл PHP, чтобы проверить ход загрузки с помощью jQuery $.ajax()
.
Проблема в том, что $_SESSION[$key]
(ключ $ содержит ключ для данных для загрузки) не устанавливается при первом вызове PHP. Я пробовал отлаживать это довольно немного, а session_id()
возвращает правильный идентификатор сеанса, поэтому сеанс определенно правильный и активен. Я также жду 1 секунду, прежде чем проверять ход загрузки, так что это не проблема времени. Я мог бы исправить это, продолжая, даже если $_SESSION[$key]
не установлен, но способ проверить, завершена ли загрузка, когда $_SESSION[$key]
не установлен.
HTML-форма создается на лету с помощью jQuery, потому что это многофайловая загрузка. Вот HTML для сгенерированной формы:
<form action="ajax/upload" id="form-HZbAcYFuj3" name="form-HZbAcYFuj3" method="post" enctype="multipart/form-data" target="frame-HZbAcYFuj3"> <iframe id="frame-HZbAcYFuj3" name="frame-HZbAcYFuj3"></iframe> <input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" value="HZbAcYFuj3"> <input type="file" id="file-HZbAcYFuj3" name="photo" accept="image/jpeg,image/pjpeg,image/png,image/gif"> <button type="button">+ Select Photo</button> </form>
Вот PHP, который JavaScript вызывает для проверки прогресса:
public function action_uploadprogress() { $id = isset($_POST['id']) ? $_POST['id'] : false; if (!$id) throw new Kohana_HTTP_Exception_404(); $progress = 0; $upload_progress = false; $key = ini_get("session.upload_progress.prefix") . $id; if (isset($_SESSION[$key])) $upload_progress = $_SESSION[$key]; else exit('100'); $processed = $upload_progress['bytes_processed']; $size = $upload_progress['content_length']; if ($processed <= 0 || $size <= 0) throw new Kohana_HTTP_Exception_404(); else $progress = round(($processed / $size) * 100, 2); echo $progress; }
Вот запрос ajax()
jQuery:
this.send_request = function() { $.ajax( { url: 'ajax/uploadprogress', type: 'post', dataType: 'html', data: { id: _this.id }, success: function(data, textStatus, jqXHR) { if (textStatus == "success") { if (data < 100) setTimeout(_this.send_request, 1000); } } } ); };
Вы отправляете POST с именем 'id' в скрипт PHP.
Однако в документации говорится, что процесс загрузки будет доступен только при отправке POST с тем же именем, что и имя session.upload_progress.name, настроенное в php.ini.
Иными словами, если для параметра session.upload_progress.name установлено значение по умолчанию (PHP_SESSION_UPLOAD_PROGRESS), вы должны изменить следующую строку в функции send_request:
Изменить:
data: { id: _this.id }
Для того, чтобы:
data: { PHP_SESSION_UPLOAD_PROGRESS: _this.id }
Вы также должны изменить $_POST['id']
на $_POST['PHP_SESSION_UPLOAD_PROGRESS']
или $_POST[ini_get("session.upload_progress.name")]
в скрипте PHP (и имя ввода тоже в случае, если оно а не по умолчанию).
Прогресс загрузки будет доступен в супергелбале $ _SESSION, когда выполняется загрузка, и когда для POST для переменной с тем же именем, что и для параметра INI session.upload_progress.name, установлено значение. Когда PHP обнаруживает такие POST-запросы, он заполняет массив в $ _SESSION, где индекс представляет собой конкатенированное значение параметров session.upload_progress.prefix и session.upload_progress.name INI. Обычно ключ извлекается, читая эти настройки INI, т.е.
Источник: http://php.net/manual/pt_BR/session.upload-progress.php
Давайте посмотрим, смогу ли я получить эту сладкую сладкую награду. Моя первая мысль состоит в том, что строка $ key не устанавливается должным образом.
Попробуйте отбросить его значение и сделать print_r для всей переменной $ _SESSION, чтобы отслеживать все.
Теперь я вообще не вижу вывод «success» от action_uploadprogress (). Я вижу 100, которые, как я полагаю, сделал, но вы не проверяете это в js. Я бы рекомендовал изучить это. Можно также отследить ваши расчеты. Я предполагаю, что это очень маловероятно, но убедитесь, что вы правильно загружаете файлы и можете определить их текущий размер без каких-либо проблем.
Другая проблема может заключаться в том, как вы обрабатываете ajax с помощью jquery. Я не уверен на 100%, но я думаю, что вариант успеха был обесценен (1.5+).
От: http://api.jquery.com/jQuery.ajax/
$.ajax({ type: "POST", url: "some.php", data: { name: "John", location: "Boston" } }).done(function( msg ) { alert( "Data Saved: " + msg ); });
Единственный способ, которым я видел успех, – вот так …
$.ajax({ type: "POST", url: '/login/spam', data: formData, success: function (data) { if (data == 'value') { //Do stuff } } });
Однако я мог бы полностью ошибаться в этом … ваша установка может быть совершенно прекрасной. То, что я хочу, чтобы вы делали, это получить непосредственно в функции success / done
alert(data); alert(textStatus); //if you still use it
Это скажет вам, если вы получаете правильный ответ от вашего запроса ajax.
Я проверю несколько раз сегодня вечером, и я буду рядом завтра, чтобы помочь. Скажите, если что-нибудь, что я сказал, поможет.