【问题标题】:Read the session data from session storage file从会话存储文件中读取会话数据
【发布时间】:2011-06-09 13:33:31
【问题描述】:

PHP unserialize() 函数面临问题,标题为抛出错误。

unserialize() [function.unserialize]: Error at offset 0 of 1781 bytes

我还尝试了返回bool(false)的session_decode()

magic_quotes_gpc 是Off。

嗯,我正在读取序列化文件的内容。文件内容如下所示。

核心|a:3:{s:23:"_session_validator_data";a: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; 房车:1.9.2.13)壁虎/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:"^@*^@_messages";a:0:{}s:20:"^@*^@_lastAddedMessage";N;}}客户|a:3:{s:23:" _session_validator_data";a: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; 房车:1.9.2.13)壁虎/20101203 Firefox/3.6.13";}s:13:"session_hosts";a:1:{s:12:"";b:1;}s:19:"wishlist_item_count";i:0;}目录|a: 3:{s:23:"_session_validator_data";a: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; 房车:1.9.2.13)壁虎/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:"^@*^@_messages";a:0:{}s:20:"^@*^@_lastAddedMessage";N;}}结帐|a:3:{s:23:" _session_validator_data";a: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; 房车:1.9.2.13)壁虎/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:"^@*^@_messages";a: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 处理的,用于在文件级别管理会话。

【问题讨论】:

  • 我不知道为什么,但内容包含 3 个单独的变量(类型 core、customer 和 checkout)。也许这导致了反序列化的问题?
  • @kevin:是的,它包含。有问题吗?
  • 我相信(不完全肯定)您一次只能[反]序列化一个变量。您是否尝试过将它们拆分并反序列化?
  • 请在此处查看我的解决方案:stackoverflow.com/questions/530761/…

标签: php serialization


【解决方案1】:

那不是合法的 PHP 序列化数据,那是 PHP 会话数据。

PHP 会话数据在内部使用序列化格式,但它本身不是序列化数据。

唯一可以安全可靠地读取会话数据的是 PHP 的会话代码。 有时可以使用正则表达式和一些创造性的编辑来阅读它,但你不能依赖这些方法。

如果您需要用户会话之外的数据,最好的办法是编写自定义会话包装器,并在数据本身发生变化时让它完成工作,而不是尝试在之后处理数据事实。

(我不是在谈论自定义会话编写代码,我是在谈论您将使用而不是直接使用 $_SESSION 的类。)

【讨论】:

  • 我已经尝试了所有可能的方法来获取我网站上的所有当前会话。现在,这是我拥有的最后一个选项,从文件中读取当前活动的会话数据并进行处理。
【解决方案2】:

如果您想解码会话数据,请使用session_decode(请参阅manual)。 unserialize 只解码单个变量,而不是会话数据。

你可以这样做:

$file = '/var/www/html/products/var/session/sess_ciktos8icvk11grtpkj3u610o3';
$contents = file_get_contents($file);
session_start();
session_decode($contents);
print_r($_SESSION);

【讨论】:

  • 试过这个返回 bool(false)
  • 在解码前尝试执行 session_start(),然后检查 $_SESSION。
  • @StasM: 添加 session_start();它返回 true,但字符串也转换为数字 1。
  • 如果返回 true,则值应在 $_SESSION 中。通话后 $_SESSION 中的内容是什么?
  • 虽然这有效,并且是唯一官方支持的方式,但它会覆盖您现有的会话。
【解决方案3】:

签出,这可能会点击你的东西

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);
}

【讨论】:

    【解决方案4】:

    以下可以是从会话文件中读取会话数据的一种方式

    //$file='/var/www/html/products/var/session/sess_ciktos8icvk11grtpkj3u610o3';
    $sSessId = 'ciktos8icvk11grtpkj3u610o3';
    session_id($sSessId);
    session_start();
    print_r($_SESSION);
    

    【讨论】:

      【解决方案5】:

      使用这个类:

          <?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.net/manual/en/function.session-decode.php#108037
      • 请说明如何设置$sessionSavePath和$sessionFileName
      • @Jonathan,您从 php.ini 文件中读取了 $sessionSavePath 参数值,并使用 sessionid 生成了 $sessionFileName 参数。这些选项来自 php.ini 文件。
      【解决方案6】:

      【讨论】:

      • 请注意,不鼓励使用 link only answers。答案应该是搜索解决方案的终点,而不是指向一个随着时间的推移经常变得陈旧的链接。请考虑在此处添加独立的概要,并保留链接作为参考。
      猜你喜欢
      • 1970-01-01
      • 2014-09-13
      • 2014-05-20
      • 1970-01-01
      • 1970-01-01
      • 2011-08-27
      • 2010-12-22
      • 2013-03-25
      • 1970-01-01
      相关资源
      最近更新 更多