问题
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);
}
}
}
);
};
回答1:
You are sending a POST called 'id' to the PHP script.
However, the documentation says that the upload progress will be available only when you send a POST with same name as session.upload_progress.name configured in php.ini.
So, in other words, if your session.upload_progress.name is set to default value (PHP_SESSION_UPLOAD_PROGRESS), you have to change the following line, in send_request function:
Change:
data: { id: _this.id }
To:
data: { PHP_SESSION_UPLOAD_PROGRESS: _this.id }
You also have to change the $_POST['id']
to $_POST['PHP_SESSION_UPLOAD_PROGRESS']
or $_POST[ini_get("session.upload_progress.name")]
in the PHP script (and the name of input too in case it's not default).
The upload progress will be available in the $_SESSION superglobal when an upload is in progress, and when POSTing a variable of the same name as the session.upload_progress.name INI setting is set to. When PHP detects such POST requests, it will populate an array in the $_SESSION, where the index is a concatenated value of the session.upload_progress.prefix and session.upload_progress.name INI options. The key is typically retrieved by reading these INI settings, i.e.
Source: http://php.net/manual/pt_BR/session.upload-progress.php
回答2:
Lets see if I can get some of that sweet sweet bounty.. My first thought is that the $key string is not getting set properly.
Try echoing its value out and doing a print_r on the entire $_SESSION variable to keep track of things.
Now I don't see a 'success' output from action_uploadprogress() at all. I see 100 which I guess indicates done but you aren't checking for that in js. I would recommend looking into that. Might as well echo out your calculations as well. I assume its very unlikely but make sure that you are uploading files properly and are able to determine their current size without any issue.
Another issue could be with how you are handling ajax with jquery. I'm not 100% sure about this but I think the success option has been depreciated (1.5+).
From : http://api.jquery.com/jQuery.ajax/
$.ajax({
type: "POST",
url: "some.php",
data: { name: "John", location: "Boston" }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
The only way I've seen success being used is like this....
$.ajax({
type: "POST",
url: '/login/spam',
data: formData,
success: function (data) {
if (data == 'value') {
//Do stuff
}
}
});
However I could be completely wrong about this....your setup might be perfectly fine. What I want you to do is get is directly in the success/done function is
alert(data);
alert(textStatus); //if you still use it
This will tell you if you are getting a proper response from your ajax query.
I will check back a few times tonight and I'll be around tomorrow to help. Tell me if anything I said helps anything.
来源:https://stackoverflow.com/questions/19336610/delay-in-populating-session-upload-progress-data