2014-09-12 4 views
2

Я искал внутреннее представление файла сеанса PHP, и я заметил, что ключи сеанса разделены символом канала |.

Прежде чем попасть в проблему, с которой я столкнулся, позвольте мне дать краткое руководство по форматированию файла сеанса. По крайней мере, так оно было отформатировано на моем Mac (10.9.4, PHP 5.4.24).

Формат Session File

Скажем, у меня есть следующий код:

$_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
  • BOOLEANS: b:1 (истина) или b:0 (false)
  • массивы: a:2:{session_value;session_value;session_value;session_value}

где четыре session_value с в массиве размера 2 являются key;valuekey;value пар.

Проблема

Вы можете видеть, что в приведенном выше, сеансовые ключи верхнего уровня разделены | характера. Но что, если одно из наших имен ключей сеанса включает символ |?

Ну, я попробовал. И когда я это сделал, весь файл сеанса (в /tmp) был пустой (и переменные определенно не были установлены). Является ли это надзором со стороны разработчиков PHP или недокументированным ограничением (или он где-то документирован)?

Это можно легко решить, поставив сами ключи $ _SESSION в кавычки или обратный сбой любого канала в строке ключа $ _SESSION. Это не большая проблема для меня лично, так как я не могу понять, почему мне нужно поставить | в ключ переменной $ _SESSION - просто интересно.

+1

Это связано с комментариями уже с 2008 года. Хотя они на самом деле не обращались к ним, они также не «фиксируют» его в ближайшее время. Вместо этого вы можете использовать другие символы. – skrilled

ответ

3

Его известная ошибка

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

Обходной обновление до 5.5.4 и использовать сериализатор сеанса php_serialize

+0

Спасибо за ссылку. Я чувствую себя глупым для Googling «php session key pipe», но не «php session key pipe bug». –

0

Используя этот файл php 'test3.php', я продемонстрировал, что оба | (труба) и! (bang) вызовет ошибку _SESSION в PHP 5.4, если они используются в ключе _SESSION. Кроме того, никакие другие символы ASCII между 0x20 и 0x7f не приводят к сбою. У меня нет простого доступа к другим версиям 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> 
Смежные вопросы