Прогресс загрузки сеанса

Я пытаюсь запустить функцию загрузки сеанса ( http://php.net/manual/en/session.upload-progress.php ) для работы в Кохане. Мне удалось заставить его работать локально без Kohana, используя следующий код:

<?php session_start(); if (isset($_GET['progress'])) { // does key exist $key = ini_get("session.upload_progress.prefix") . 'demo'; if ( !isset( $_SESSION[$key] ) ) exit( "uploading..." ); // workout percentage $upload_progress = $_SESSION[$key]; $progress = round( ($upload_progress['bytes_processed'] / $upload_progress['content_length']) * 100, 2 ); exit( "Upload progress: $progress%" ); } ?> <!doctype html> <head> </head> <body> <section> <h1>Upload Form</h1> <form action="" method="POST" enctype="multipart/form-data" target="upload-frame"> <input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="<?php //echo $uid; ?>demo"> <p> <label>File:</label> <input type="file" name="file" required="required"> </p> <p><input type="submit" name="submit" value="Upload"></p> </form> <iframe id="upload-frame" name="upload-frame" width="1280" height="600"></iframe> <div id="file_upload_progress"></div> </section> <script src="jquery-1.7.1.min.js"></script> <script> $(document).ready(function() { var uploading = false; $('form').submit(function() { uploading = true; $('#upload-frame').one('load', function(){ uploading = false; }); function update_file_upload_progress() { $.get("?progress", function(data) { $("#file_upload_progress").html(data); if (uploading) { setTimeout( update_file_upload_progress, 500 ); } }) .error(function(jqXHR, error) { alert(error); }); } // first call update_file_upload_progress(); }); }); </script> </body> </html> 

Однако, когда я использую этот код в Kohana (разделяя PHP на контроллер, конечно), переменная $_SESSION не создается для отслеживания хода загрузки.

Я считаю, что это связано с тем, как работают занятия в Кохане. Я не могу иметь session_start() в начале скрипта, поскольку он конфликтует с сеансом Kohana, который уже запущен. Если я $_SESSION содержимое $_SESSION или Session::instance() переменная, которая должна быть добавлена ​​функциональностью PHP Upload Progress, отсутствует.

Итак, как мне заставить переменную сеанса работать с Kohana?

ОБНОВИТЬ

С тех пор я создал чистую установку Kohana, чтобы помочь сузить эту проблему. Я обнаружил, что, не создавая экземпляр класса Session в Kohana, я могу использовать вышеприведенный код, и он отлично работает.

Однако, когда Session класс Session который должен быть для моего веб-приложения, он перестает работать, а переменная $_SESSION содержащая прогресс загрузки, больше не создается. Это заставляет меня думать, что проблема заключается в том, как Кохана управляет информацией о сеансе. Я попытался отключить шифрование с настройками конфигурации, но это не изменило ситуацию.

Я использую собственный сеанс.

Имя cookie сеанса должно быть точно таким же, как тот, который задан в php config ( session.name ), например:

 return array( 'native' => array( 'encrypted' => FALSE, 'name' => ini_get('session.name'), ), ); 

Если вы не хотите использовать имя cookie по умолчанию для PHP, вы не сможете обойти это, установив значение во время выполнения, то есть это не сработает:

 ini_set('session.name', 'my_kohana_session_name'); 

Вы обойдете это, установив значение в файле .htaccess:

 php_flag session.name "my_kohana_session_name" 

Таким образом, вы можете сохранить php.ini нетронутым, но вы можете сохранить свое собственное имя cookie для своего приложения Kohana.

Мои тесты показали, что шифрование сеанса не влияет на информацию о ходе загрузки при использовании собственного драйвера сеанса. Это, конечно, потому, что шифрование не используется при использовании встроенного драйвера. 😉

PS. Одна вещь, которую я также предлагаю – убедитесь, что запрос ajax не кэшируется. Было довольно много случаев, когда он был кэширован и не показывал свежих ответов.

Я нашел решение.

То, что я сделал, – это изолированный код, который считывает переменную PHP $_SESSION в свой собственный Controller . В моем случае у меня есть контроллер AJAX для общих проверок AJAX, таких как проверка электронных писем, веб-URL и т. Д. Контроллер extends от Controller по умолчанию, так что он не наследует какую-либо информацию о сеансе от моего пользовательского контроллера (от чего распространяются мои другие контроллеры) ,

Поэтому мой новый автономный Controller выглядит так:

 <?php defined('SYSPATH') or die('No direct script access.'); class Controller_Ajax extends Controller { public function action_upload_progress() { // get upload progress key $key = (!empty($_POST['key'])) ? $_POST['key'] : FALSE; // start session to get PHP 5.4 generated $_SESSION variables session_start(); // does key exist $key = ini_get("session.upload_progress.prefix") . $key; if ( !isset( $_SESSION[$key] ) ) { exit( "uploading..." ); } // workout percentage $upload_progress = $_SESSION[$key]; $progress = round( ($upload_progress['bytes_processed'] / $upload_progress['content_length']) * 100, 2 ); exit( "Upload progress: $progress%" ); } } 

Я использую тот же код, что и раньше, для реальной формы и делаю небольшую настройку для JavaScript, запрашивая этот контроллер / действие для получения данных о ходе загрузки. Задача решена!