问题
I was looking at the internal representation of PHP session file and I noticed that the session keys are separated by the pipe character |
.
Before getting into the problem I encountered, let me give a quick tutorial on how the session file is formatted. At least, this is how it was formatted on my Mac (10.9.4, PHP 5.4.24).
Session File Format
Say I have the following code:
$_SESSION["age"] = 26;
$_SESSION["car"] = "Mazda";
$_SESSION["nerdy"] = true;
$_SESSION["likes"] = array(42, "being meta");
$_SESSION["stats"] = array("bmi" => 1000);
Then it gets stored in the session variable like this:
age|i:26;car|s:5:"Mazda";nerdy|b:1;
likes|a:2:{i:1;i:42;i:2;s:10:"being meta"}
stats|a:1:{s:3:"bmi";i:1000}
The general format is
session_key|session_value[;session_key|value] etc.
where session_value
is of the general form
type[:size]:value
More specifically (if anyone's interested),
- strings:
s:3:"some text"
- integers:
i:4
- booleans:
b:1
(true) orb:0
(false) - arrays:
a:2:{session_value;session_value;session_value;session_value}
where the four session_value
s in the array of size 2 are the key;value
key;value
pairs.
The Problem
You can see that in the above, the top-level session keys are separated by the |
character. But what if one of our session key names includes the |
character?
Well, I tried it. And when I did, the entire session file (in /tmp
) was blank (and the variables were definitely not set). Is this an oversight by the PHP devs or an undocumented limitation (or is it documented somewhere)?
This could be easily solved by putting the $_SESSION keys themselves in quotes or backslashing any pipe in a $_SESSION key string. This isn't a big problem for me personally, since I can't fathom why I would need to put a |
in a $_SESSION variable key - just curious about it.
回答1:
Its a known bug
https://bugs.php.net/bug.php?id=33786
The work around is update to 5.5.4 and use the php_serialize session serializer
回答2:
Using this php file 'test3.php', I demonstrated that both | (pipe) and ! (bang) will cause _SESSION to fail in PHP 5.4 if they are used in a _SESSION key. Also, no other ASCII characters between 0x20 and 0x7f cause it to fail. I don't have easy access to other versions of PHP to empirically check their behavior.
<?php
session_start( );
?><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test session keys</title>
</head>
<body>
<form method="post" target="test3.php">
<input type="submit" id="submit" name="submit" value="Submit">
<?php
echo "<br>_SESSION...<br>";
var_dump( $_SESSION );
echo "\n".'<br><input type="text" id="text" name="text" length="1" ';
if( $_SERVER[ 'REQUEST_METHOD' ] != 'POST' ) {
$t = chr( 32 );
echo 'value="&#'.ord( $t ).';">';
$_SESSION[ 'key' ] = ' ';
$str = 'first';
} else {
$str = 'good';
if( count( $_SESSION ) != 2 ) {
$str = 'BAD';
}
$_SESSION = array( );
$t = substr( $_POST[ 'text' ], 0, 1);
echo 'value="&#'.(ord($t) + 1 ).';">';
$_SESSION[ 'key' ] = chr(ord($t) + 1 );
}
echo "\n".'<br><input type="text" id="check" name="check" length="1" value="&#'.ord( $t ).';">';
echo "\n".'<br><input type="text" id="check2" name="check2" length="6" value="%'.bin2hex( $t ).'";">';
echo '<span id="success"></span>';
echo "<script> document.getElementById( 'success' ).innerHTML = '".$str."'; </script>";
$_SESSION[ "alpha".$_SESSION['key']."four" ] = 'Hello World';
?>
</form>
</body>
</html>
来源:https://stackoverflow.com/questions/25817462/reserved-characters-in-php-session-variable-keys