【问题标题】:Reserved characters in PHP $_SESSION variable keysPHP $_SESSION 变量键中的保留字符
【发布时间】:2014-09-12 21:56:58
【问题描述】:

我正在查看 PHP 会话文件的内部表示,我注意到会话密钥由管道字符 | 分隔。

在讨论我遇到的问题之前,让我快速介绍一下会话文件的格式。至少,这是它在我的 Mac 上的格式(10.9.4,PHP 5.4.24)。

会话文件格式

假设我有以下代码:

$_SESSION["age"] = 26;
$_SESSION["car"] = "Mazda";
$_SESSION["nerdy"] = true;
$_SESSION["likes"] = array(42, "being meta");
$_SESSION["stats"] = array("bmi" => 1000);

然后它会像这样存储在会话变量中:

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}

一般格式是

session_key|session_value[;session_key|value] etc.

其中session_value 是一般形式

type[:size]:value

更具体地说(如果有人感兴趣的话),

  • 字符串:s:3:"some text"
  • 整数:i:4
  • 布尔值:b:1(真)或b:0(假)
  • 数组:a:2:{session_value;session_value;session_value;session_value}

其中大小为 2 的数组中的四个 session_values 是 key;value key;value 对。

问题

您可以在上面看到,顶级会话密钥由| 字符分隔。但是,如果我们的会话密钥名称之一包含| 字符怎么办?

嗯,我试过了。当我这样做时,整个会话文件(/tmp)是空白(并且变量肯定没有设置)。这是 PHP 开发人员的疏忽还是未记录的限制(或者是否记录在某处)?

这可以通过将 $_SESSION 键本身放在引号中或反斜杠在 $_SESSION 键字符串中的任何管道中轻松解决。这对我个人来说不是什么大问题,因为我无法理解为什么我需要将 | 放在 $_SESSION 变量键中 - 只是好奇。

【问题讨论】:

  • 早在 2008 年就已经通过 cmets 提出了这个问题。虽然他们还没有真正解决这个问题,但他们也不会很快“修复”它。您可以改用其他字符。

标签: php session special-characters file-format


【解决方案1】:

这是一个已知的错误

https://bugs.php.net/bug.php?id=33786

解决方法是更新到 5.5.4 并使用 php_serialize 会话序列化程序

【讨论】:

  • 感谢您的链接。我对谷歌搜索“php session key pipe”而不是“php session key pipe bug”感到愚蠢。
【解决方案2】:

使用这个 php 文件“test3.php”,我证明了两者 | (管道)和! (bang) 如果在 _SESSION 键中使用它们,将导致 _SESSION 在 PHP 5.4 中失败。此外,0x20 和 0x7f 之间的其他 ASCII 字符不会导致它失败。我无法轻松访问其他版本的 PHP 来凭经验检查它们的行为。

<?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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-11-19
    • 1970-01-01
    • 2012-08-16
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多