I'm trying to make work an upload_progress session after a bunch of changes in php.ini like:
session.upload_progress.enabled = On
;session.upload_progress.cleanup = On
session.upload_progress.prefix = "upload_progress_"
session.upload_progress.name = "123"
session.upload_progress.freq = "1%"
session.upload_progress.min_freq = "1"
and created and html based page with form to submit files:
<form action="upload_progress.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
<input type="file" name="file1" />
<input type="file" name="file2" />
<input type="submit" />
</form>
and then the server side script which uploading files properly:
session_start();
move_uploaded_file($_FILES['file1']['tmp_name'], './uploads/'.$_FILES['file1']['name']);
move_uploaded_file($_FILES['file2']['tmp_name'], './uploads/'.$_FILES['file2']['name']);
print_r($_SESSION);
There is an empty array in the $_SESSION
globals, although files upload completed correctly. What is the problem with session settings?
I'm using PHP 5.4.5
Notice: Undefined index: upload_progress_123 in C:\apache\localhost\www\upload_progress.php on line 13
Upload progress via session in PHP is pretty tricky and not all context and circumstances are well documented. Number of similar questions indicates it causes troubles. I've personally lost more than a day on this so here is my advice to help you out.
php.ini
session.upload_progress.cleanup = OffThis way you can check the contents of a session after the upload is done.
Find out where session are being stored (variable session.save_path
in php.ini
, typical value on linux machines is /var/lib/php/sessions
) and inspect them, look for an index named upload_progress_xxxxxxxxxxx
after upload is initiated.
To activate a particular upload progress tracking usually a hidden HTML form element is used. It must be sent before the file. If you think about it it's logical: when PHP is processing the request it must first encounter the signal to start tracking the file upload progress and after that recognize the file itself. The other way around, it won't work.
<form action="upload_progress.php" method="POST" enctype="multipart/form-data">
<input type="hidden"
name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
<input type="file" name="myfile1" />
<input type="submit" />
</form>
Carefully with AJAX submitting. Although it's unlikely, some JS libraries may change the order of elements in a HTTP request. You should check the actual HTTP communication using Developer tools in you browser and ensure that the order of elements being sent is in accordance with the previous point.
Session name. While you may use any possible session name in your code, PHP does not know it and writes the upload progress always to the default session, usually PHPSESSID
(consult your php.ini
's property session.name
to check the actual value.) This behavior is not a bug.
If you mind two sessions are being created you should either change your code to use the default value or change the default value of session.name
which is not always possible (e.g. shared hosting). Notice that the value can also be changed via .htaccess
.
Some PHP frameworks (Zend, Cake PHP) have it's own structure of session contents and PHP engine will corrupt the session when writing the upload progress into the session. Causing loss of stored information and thus effects like sign-outs, damages to tracking etc. Issue, issue, issue. I came to the conclusion that in that case 2 different sessions must be used.
I'm using Zend Framework and I ended up with two separate sessions. I use the following plain PHP script to report a specific file upload progress. The script is totally isolated from Zend Framework and uses the default PHPSESSID
namespace.
session_start();
if(!isset($_GET['id']))
die("unsupported");
$id = $_GET['id'];
if(!preg_match('/^[a-zA-Z0-9]{1,32}$/', $id))
die("unsupported");
$sessionKey = ini_get('session.upload_progress.prefix') . $id;
$uploadInfo = (isset($_SESSION[$sessionKey])) ? $_SESSION[$sessionKey] : null;
$status = [
'total' => 0,
'current' => 0,
'rate' => 0,
'message' => '',
'done' => false,
];
if($uploadInfo === null)
{
header('Content-Type: application/json');
echo json_encode($status);
return;
}
$status = $uploadInfo + $status;
$status['total'] = $status['content_length'];
$status['current'] = $status['bytes_processed'];
$time = time() - $status['start_time'];
$status['rate'] = ($time > 0) ? $status['bytes_processed'] / $time : 0;
if (!empty($status['cancel_upload'])) {
$status['done'] = true;
$status['message'] = 'The upload has been canceled';
}
header('Content-Type: application/json');
echo json_encode($status);
The application made on top of Zend Framework sets it's own session namespace in Module.php
's onBootstrap()
method:
$sessionManager = new \Zend\Session\SessionManager();
$sessionManager->setName('myFancyNamespace');
$sessionManager->start();
Upload progress can be seen in $_SESSION Array, so can check progress in another php request.
$_SESSION will be available till files are being uploaded not after files have been uploaded. so once you handled files it will be gone. you should print_r this in separate request while files are being uploaded. not in the same request.
like in this example
check_progress.php
<?php
if(isset($_SESSION['upload_progress_123']))){
print_r($_SESSION['upload_progress_123']);
}
?>
Sample array
<?php
$_SESSION["upload_progress_123"] = array(
"start_time" => 1234567890, // The request time
"content_length" => 57343257, // POST content length
"bytes_processed" => 453489, // Amount of bytes received and processed
"done" => false, // true when the POST handler has finished, successfully or not
"files" => array(
0 => array(
"field_name" => "file1", // Name of the <input/> field
// The following 3 elements equals those in $_FILES
"name" => "foo.avi",
"tmp_name" => "/tmp/phpxxxxxx",
"error" => 0,
"done" => true, // True when the POST handler has finished handling this file
"start_time" => 1234567890, // When this file has started to be processed
"bytes_processed" => 57343250, // Number of bytes received and processed for this file
),
// An other file, not finished uploading, in the same request
1 => array(
"field_name" => "file2",
"name" => "bar.avi",
"tmp_name" => NULL,
"error" => 0,
"done" => false,
"start_time" => 1234567899,
"bytes_processed" => 54554,
),
)
);
Complete tutorial can be found here as pilif said
http://www.sitepoint.com/tracking-upload-progress-with-php-and-javascript/
http://oliversmith.io/technology/2011/12/04/php-5-4-file-upload-progress-and.html5-progress-bars/
see this answer as well. PhP Upload progress in PhP 5.4 is not working. Session variables not set
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With