CakeFest 2024: The Official CakePHP Conference

Oturumu Karşıya Yükleme Süreci

session.upload_progress.enabled INI seçeneği etkin ise, PHP karşıya yüklenen bağımsız dosyaların karşıya yükleme sürecini izleyebilecektir. Bu bilgi, yükleme isteğinin kendisi için yararlı bir özellik değildir, ancak bir uygulama dosya yükleme sırasında, durumu denetim altında tutmak için ayrı bir uç noktaya (örneğin XHR aracılığıyla) bir POST isteği gönderebilir.

Karşıya yükleme süreci, bir yükleme devam ederken ve session.upload_progress.name INI ayarıyla aynı isme sahip bir değişken POST edilirken $_SESSION süper küreselinde kullanılabilir olacaktır. PHP bu tür POST isteklerini algıladığında, $_SESSION altında bir dizi oluşturur; burada anahtar, session.upload_progress.prefix ve session.upload_progress.name INI seçeneklerinin birleşiminden oluşur. Anahtar genellikle bu INI ayarlarından elde edilir. Örnek:

<?php
$key
= ini_get("session.upload_progress.prefix") . $_POST[ini_get("session.upload_progress.name")];
var_dump($_SESSION[$key]);
?>

$_SESSION[$key]["cancel_upload"] anahtarına true atayarak, sürmekte olan dosya yüklemesini iptal etmek de mümkündür. Aynı istekte birden fazla dosya yüklerken, bu yalnızca devam etmekte olan dosya yüklemesini ve bekleyen dosya yüklemelerini iptal eder, ancak başarıyla tamamlanmış yüklemeleri kaldırmaz. Bir yükleme bu şekilde iptal edildiğinde $_FILES dizisindeki error anahtarına UPLOAD_ERR_EXTENSION atanır.

session.upload_progress.freq ve session.upload_progress.min_freq INI seçenekleri, karşıya yükleme süreci bilgisinin ne sıklıkta yeniden hesaplanması gerektiğini denetler. Bu iki ayar için uygun bir miktar dışında, bu özelliğin getirdiği ek bir yük neredeyse yoktur.

Örnek 1 - Örnek bilgi

Karşıya yükleme süreci için dizi yapılandırma örneği

<form action="upload.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>

Oturumda saklanan veri şöyle görünür:

<?php
$_SESSION
["upload_progress_123"] = array(
"start_time" => 1234567890, // İstek zamanı
"content_length" => 57343257, // POST içeriğinin uzunluğu
"bytes_processed" => 453489, // Alınan ve işlenen bayt miktarı
"done" => false, // POST işleyici sonlanınca başarılı olsun olmasın true
"files" => array(
0 => array(
"field_name" => "file1", // <input/> alanındaki isim
// Aşağıdaki 3 eleman $_FILES içindekilerle aynıdır
"name" => "foo.avi",
"tmp_name" => "/tmp/phpxxxxxx",
"error" => 0,
"done" => true, // POST işleyici dosyayla işini bitirince true
"start_time" => 1234567890, // Dosyanın işleme alındığı zaman
"bytes_processed" => 57343250, // Dosya işlenirken alınan ve gönderilen bayt miktarı
),
// Aynı istekte, karşıya yüklenmesi tamamlanmamış başka bir dosya
1 => array(
"field_name" => "file2",
"name" => "bar.avi",
"tmp_name" => NULL,
"error" => 0,
"done" => false,
"start_time" => 1234567899,
"bytes_processed" => 54554,
),
)
);

Uyarı

Bunun düzgün çalışması için HTTP sunucusunun isteği tamponlama özelliği devre dışı bırakılmalıdır, aksi takdirde PHP dosya yüklemesini yalnızca dosya tam olarak yüklendikten sonra görebilir. Nginx gibi sunucuların oldukça büyük istekleri tamponladıkları bilinmektedir.

Dikkat

Karşıya yükleme süreci bilgisi, herhangi bir betik yürütülmeden önce oturuma yazılır. Bu nedenle oturum adını ini_set() veya session_name() yoluyla değiştirmek, içinde karşıya yükleme süreci bilgisi bulunmayan bir oturum verecektir.

add a note

User Contributed Notes 12 notes

up
165
s.zarges
11 years ago
Note, this feature doesn't work, when your webserver is runnig PHP via FastCGI. There will be no progress informations in the session array.
Unfortunately PHP gets the data only after the upload is completed and can't show any progress.

I hope this informations helps.
up
63
howtomakeaturn
8 years ago
ATTENTION:

Put the upload progress session name input field BEFORE your file field in the form :

<form action="upload.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>

If you make it after your file field, you'll waste a lot of time figuring why (just like me ...)

The following form will make you crazy and waste really a lot of time:

<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="file" name="file1" />
<input type="file" name="file2" />
<input type="hidden" name="<?php echo ini_get("session.upload_progress.name"); ?>" value="123" />
<input type="submit" />
</form>

DON'T do this!
up
24
Anonymous
10 years ago
While the example in the documentation is accurate, the description is a bit off. To clarify:

PHP will populate an array in the $_SESSION, where the index is a concatenated value of the session.upload_progress.prefix and the VALUE of the POSTed session.upload_progress.name variable.
up
14
isius
11 years ago
If you're seeing
"PHP Warning: Unknown: The session id is too long or contains illegal characters, valid characters are a-z, A-Z, 0-9 and '-,' in Unknown on line 0",
then a misplaced input could be the cause. It's worth mentioning again that the hidden element MUST be before the file elements.
up
6
jortsc at gmail dot com
10 years ago
Note that if you run that code and you print out the content of $_SESSSION[$key] you get an empty array due that session.upload_progress.cleanup is on by default and it cleans the progress information as soon as all POST data has been read.

Set it to Off or 0 to see the content of $_SESSION[$key].
up
2
alice at librelamp dot com
7 years ago
There were two gotchas that got me with implementing this.

The first - if you use session_name() to change the name of sessions, this will not work. I discovered this by looking at phpinfo() and seeing that is saw a different session name.

At least in Apache, a better way to set the session is in your apache config use

php_value session.name "your custom name"

It goes within the Directory directive, might work in .htaccess - I don't know.

-=-

Secondly - in apache, don't use mod_mpm_prefork.so

That was the problem I had, that's the default in CentOS 7.

The problem is it causes Apache to wait with any additional requests until the upload is finished.

Commenting that module out and using mod_mpm_worker.so instead fixed that problem, and the progress meter worked.
up
2
ricki at rocker dot com
8 years ago
session.upload_progress updates completely ignore custom session handlers set via session_set_save_handler()
up
5
nihaopaul at gmail dot com
11 years ago
it should be noted that the hidden element come before the file element otherwise you wont get any updates.
up
1
StrateGeyti
9 years ago
It seems like if you send a form with the field like :

<?php echo '<input type="hidden" name="'.ini_get('session.upload_progress.name') .'" value="123" />'; ?>

without any field type "file", the server respons will be an 500 error.
up
2
Anonymous
10 years ago
dont't forget, that the session has to be initialized before the form is generated, otherwise the mentioned example above won't work.
up
-12
wilsonr at st dot com
9 years ago
If you have upload progress enabled in your php.ini, and you have

<form enctype="multipart/form-data" ...
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" ...

in your form, but you DON'T specify an input with 'type="file"', you may lose your session ID. I am using PHP 5.5 and I lose my session ID on the second loading of such a page. To prevent this, you can use a dummy input as follows:

<form enctype="multipart/form-data" ... >
<input type="hidden" name="PHP_SESSION_UPLOAD_PROGRESS" ... />
<input type="file"' name="dummy" style="display="none;" ... />
To Top