I'm trying to check the progress of files uploaded. I'm using the Kohana framework which has a Session class, but for the upload progress I'm using native PHP sessions. I'm calling session_start()
in Kohana's bootstrap.php, which means session_start()
will be called on every page request.
After the upload form is submitted, I wait 1 second and then begin calling a PHP file to check the upload progress using jQuery $.ajax()
.
The problem is that $_SESSION[$key]
($key contains the key for the upload data) isn't set on the first call to the PHP. I've tried debugging this quite a bit, and session_id()
returns the correct session ID, so the session is definitely the right one and is active. I'm also waiting 1 second before checking the upload progress, so it's not a timing issue. I could fix this by continuing even if $_SESSION[$key]
is not set, but the way to check if the upload is complete is when $_SESSION[$key]
is unset.
The HTML form is created on-the-fly with jQuery because this is a multi-file upload. Here's the HTML for a generated form:
<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>
Here's the PHP that the JavaScript calls to check the progress:
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;
}
Here's the jQuery ajax()
request:
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);
}
}
}
);
};