1. Reply to ac's post:
As I mentioned at http://us.php.net/manual/en/function.unserialize.php#76977 , the regular expression used to unserialize a PHP session data won't work if the session data contains string variable which contains character '|'.
Here is a simple example I just come up with to show when the function unserializesession() won't work.
<?php
function unserializesession($data) {
$vars=preg_split('/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff^|]*)\|/',
$data,-1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
for($i=0; $vars[$i]; $i++) $result[$vars[$i++]]=unserialize($vars[$i]);
return $result;
}
session_start();
$_SESSION['var'] = 'a|b';
$str = session_encode();
$arr = unserializesession($str);
print_r($_SESSION);
echo "<br />\n";
print_r($arr);
?>
2. Reply to bmorel's post:
Your function session_real_decode() is very nice to decode session data without involving with session functions. It works in most cases, but when dealing with reference variables, there is another case which should also be handled:
<?php case 'r': /* reference */ // R in lowercase ?>
I found this bug on PHP 5.1.6 several months ago, but don't know if it exsits in other version of PHP or not. Also, I am not sure if similiar bugs exist when handling other data types.
So here is my suggestion to revise the function,
2.1.
change the switch statement from
<?php switch ($str[$q]) { ?>
to
<?php switch (strtolower($str[$q])) { ?>
2.2.
In all case statements, use lowercase characters only for character comparison. For example,
<?php case 'R': /* reference */ ?>
should be be written as
<?php case 'r': /* reference */ ?>
(I don't want to put long code here, so just leave pieces of code to save spaces)