Зарезервированные символы в переменных переменных PHP $ _SESSION

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

Прежде чем попасть в проблему, с которой я столкнулся, позвольте мне дать краткое руководство по форматированию файла сеанса. По крайней мере, так оно было отформатировано на моем 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
  • booleans: b:1 (true) или b:0 (false)
  • массивы: a:2:{session_value;session_value;session_value;session_value}

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

Проблема

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

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

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

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

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

Работа вокруг – обновление до 5.5.4 и использование сериализатора сеанса php_serialize

Используя этот 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>