Чтение данных сеанса из файла хранения сеанса
Столкнувшись с проблемой с PHP unserialize()
функция как названо это бросает ошибку.
unserialize() [function.unserialize]: Error at offset 0 of 1781 bytes
Я также попробовал session_decode()
которые возвращаются bool(false)
magic_quotes_gpc
является Off
,
Ну, я читаю содержимое файла, который сериализован. Содержимое файла выглядит следующим образом.
Ядро | а:3:{s:23:"_session_validator_data"; а:4:{s:11:"remote_addr";s:15:"117.241.113.248";s:8:"HTTP_VIA";s:0:"";s:20:"http_x_forwarded_for";s:0:"";s:15:"http_user_agent";s:90:"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1,9.2.13) Gecko/20101203 Firefox/3.6.13";}s:13:"session_hosts";a:1:{s:12:"";b:1;}s:8:"messages";O:34:"Mage_Core_Model_Message_Collection":2:{s:12:"^@*^@_ сообщения"; а:0:{}s:20:"^@*^@_lastAddedMessage";N;}} клиент | а:3:{s:23:"_session_validator_data"; а:4:{s:11:"remote_addr";s:15:"117.241.113.248";s:8:"HTTP_VIA";s:0:"";s:20:"http_x_forwarded_for";s:0:"";s:15:"http_user_agent";s:90:"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";}s:13:"session_hosts"; а: 1: {s: 12:" "; б:1;}s:19:"wishlist_item_count"; я:0;} Каталог | а:3:{s:23:"_session_validator_data"; а:4:{s:11:"remote_addr";s:15:"117.241.113.248";s:8:"HTTP_VIA";s:0:"";s:20:"http_x_forwarded_for";s:0:"";s:15:"http_user_agent";s:90:"Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.13) Gecko/20101203 Firefox/3.6.13";}s:13:"session_hosts";a:1:{s:12:"";b:1;}s:8:"messages";O:34:"Mage_Core_Model_Message_Collection":2:{s:12:"^@*^@_ сообщения"; а:0:{}s:20:"^@*^@_lastAddedMessage";N;}} контроль | а:3:{s:23:"_session_validator_data"; а:4:{s:11:"remote_addr";s:15:"117.241.113.248";s:8:"HTTP_VIA"; s: 0: ""; s: 20: "http_x_forwarded_for"; s: 0: ""; s: 15: "http_user_agent"; s: 90: "Mozilla / 5.0 (Windows; U; Windows NT 5.1; EN-US; rv: 1.9.2.13) Gecko / 20101203 Firefox / 3.6.13 ";} s: 13:" session_hosts "; a: 1: {s: 12:" "; b: 1;} s: 8:" messages "; O: 34: "Mage_Core_Model_Message_Collection": 2: {ы: 12: "^ @ * @ ^ _ сообщения"; а: 0: {} s: 20: "^ @ * ^ _ @ lastAddedMessage"; N;}}
мой код PHP ниже
$file='/var/www/html/products/var/session/sess_0ehb7ek0hmunqo3kq70t0t6mb0';
$contents=file_get_contents($file);
$data = unserialize($contents);
var_dump($data);
Я уже попробовал stripslashes()
перед десериализацией данных. Не уверен, где проблема в данных. Я не могу изменить механизм хранения данных в файл, потому что это обрабатывается Magento для управления сеансом на уровне файла.
6 ответов
Если вы хотите декодировать данные сеанса, используйте session_decode
(см. руководство). unserialize
декодирует только отдельные переменные, а не данные сеанса.
Вы можете сделать что-то вроде:
$file = '/var/www/html/products/var/session/sess_ciktos8icvk11grtpkj3u610o3';
$contents = file_get_contents($file);
session_start();
session_decode($contents);
print_r($_SESSION);
Используйте этот класс:
<?php
class Session {
public static function unserialize($session_data) {
$method = ini_get("session.serialize_handler");
switch ($method) {
case "php":
return self::unserialize_php($session_data);
break;
case "php_binary":
return self::unserialize_phpbinary($session_data);
break;
default:
throw new Exception("Unsupported session.serialize_handler: " . $method . ". Supported: php, php_binary");
}
}
private static function unserialize_php($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
if (!strstr(substr($session_data, $offset), "|")) {
throw new Exception("invalid data, remaining: " . substr($session_data, $offset));
}
$pos = strpos($session_data, "|", $offset);
$num = $pos - $offset;
$varname = substr($session_data, $offset, $num);
$offset += $num + 1;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
private static function unserialize_phpbinary($session_data) {
$return_data = array();
$offset = 0;
while ($offset < strlen($session_data)) {
$num = ord($session_data[$offset]);
$offset += 1;
$varname = substr($session_data, $offset, $num);
$offset += $num;
$data = unserialize(substr($session_data, $offset));
$return_data[$varname] = $data;
$offset += strlen(serialize($data));
}
return $return_data;
}
}
?>
Использование:
<?php
Session::unserialize(file_get_contents($sessionSavePath."/".$sessionFileName);
?>
Это работа!
Это недопустимые сериализованные данные PHP, это данные сеанса PHP.
Данные сеанса PHP используют внутри себя сериализованный формат, но это не сами сериализованные данные.
Единственное, что может безопасно и разумно читать данные сеанса, это код сеанса PHP. Иногда его можно прочитать с помощью регулярного выражения и некоторого творческого редактирования, но вы не можете полагаться на эти методы.
Если вам нужны данные вне сеанса пользователя, лучше всего написать пользовательскую оболочку сеанса и позволить ей выполнять работу при изменении самих данных, а не пытаться работать с данными после факта.
(Я не говорю о собственном коде написания сессии, я говорю о классе, который вы бы использовали вместо $_SESSION
непосредственно.)
Следующее может быть способом чтения данных сеанса из файла сеанса
//$file='/var/www/html/products/var/session/sess_ciktos8icvk11grtpkj3u610o3';
$sSessId = 'ciktos8icvk11grtpkj3u610o3';
session_id($sSessId);
session_start();
print_r($_SESSION);
Проверить, это может нажать что-то
function read($filename)
{
session_save_path("/tmp/tst");
session_start();
echo $sCurrentFile = "/tmp/tst/sess_".session_id();
$sFileToRead = $filename;
if( !file_exists($sFileToRead) || !$sessionData=(string)@file_get_contents($sFileToRead) )
{
echo "file does not exist";
}
$fh = fopen($sCurrentFile, 'w') or die("can't open file");
fwrite($fh, $sessionData);
fclose($fh);
$_SESSION["mytest"] = 444;
print_r($_SESSION);
}