【问题标题】:Uncaught exception 'Exception' with message 'Serialization of 'SimpleXMLElement' is not allowed'未捕获的异常 'Exception' 和消息'SimpleXMLElement' 的序列化是不允许的'
【发布时间】:2011-08-28 20:58:54
【问题描述】:

我不确定为什么会出现这种情况。我不是序列化 XML,而是我从 RSS 提要创建的数组(注意这只是一个 sn-p):

$game_data = array (
    'sysreqos'  => $game->systemreq->pc->sysreqos,
    'sysreqmhz' => $game->systemreq->pc->sysreqmhz,
    'sysreqmem' => $game->systemreq->pc->sysreqmem,
    'sysreqdx'  => $game->systemreq->pc->sysreqdx,
    'sysreqhd'  => $game->systemreq->pc->sysreqhd,
);

然后我序列化它$some_var = serialize($game_data) 并写入一个文本文件fputs($fh,$some_var)

但它并没有那么远,它在序列化行出错:

未捕获的异常 'Exception' 带有消息“不允许序列化 'SimpleXMLElement'”

【问题讨论】:

    标签: php exception serialization simplexml


    【解决方案1】:

    在 Classes and Objects 文档中,有这样的内容:为了能够 unserialize() 一个对象,需要定义该对象的类。

    在 PHP 5.3 之前,这不是问题。但是在 PHP 5.3 之后,由 SimpleXML_Load_String() 生成的对象不能被序列化。尝试这样做将导致运行时失败,引发异常。如果您将这样的对象存储在 $_SESSION 中,您将收到一个执行后错误,内容如下:

    致命错误:在 [no active file] 中未捕获的异常 'Exception' 带有消息 'SimpleXMLElement' 的序列化是不允许的':0 堆栈跟踪:#0 {main} 在第 0 行的 [no active file] 中抛出

    会话的全部内容将丢失。希望这可以节省一些时间!

    <?php // RAY_temp_ser.php
    error_reporting(E_ALL);
    session_start();
    var_dump($_SESSION);
    $_SESSION['hello'] = 'World';
    var_dump($_SESSION);
    
    // AN XML STRING FOR TEST DATA
    $xml = '<?xml version="1.0"?>
    <families>
      <parent>
        <child index="1" value="Category 1">Child One</child>
      </parent>
    </families>';
    
    // MAKE AN OBJECT (GIVES SimpleXMLElement)
    $obj = SimpleXML_Load_String($xml);
    
    // STORE THE OBJECT IN THE SESSION
    $_SESSION['obj'] = $obj;
    

    作者:Ray.Paseur

    参考:http://php.net/manual/en/function.unserialize.php

    我所做的是正如“Stefan Gehrig”所说,将 XML 数据转换为字符串

    $_SESSION['obj'] = (string)$obj;
    

    【讨论】:

      【解决方案2】:

      您必须将 XML 数据转换为字符串,因为在内部它们都是 SimpleXMLElements。

      $game_data = array (
                      'sysreqos'       => (string)$game->systemreq->pc->sysreqos,
                      'sysreqmhz'      => (string)$game->systemreq->pc->sysreqmhz,
                      'sysreqmem'      => (string)$game->systemreq->pc->sysreqmem,
                      'sysreqdx'       => (string)$game->systemreq->pc->sysreqdx,
                      'sysreqhd'       => (string)$game->systemreq->pc->sysreqhd
                  );
      

      或者更优雅一点:

      $game_data  = array();
      $properties = array('sysreqos', 'sysreqmhz', 'sysreqmem', 'sysreqdx', 'sysreqhd');
      foreach ($properties as $p) {
          $game_data[$p] = (string)$game->systemreq->pc->$p;
      }
      

      【讨论】:

      • 这让我感到困惑的唯一原因是,当我通过 MYSQL 执行此操作时,它可以完美地插入 tablname 值(见上文),没有类型转换 - 有趣但非常感谢!!
      • 当您将数据连接成 SQL INSERT 查询字符串时,它会自动转换为字符串。但是,如果您将数据放入某个 PHP 数据结构中,它将保持其原始数据类型(即SimpleXMLElement)。
      • 超级!再次感谢。顺便提一句。你能得到选票吗?我认为你的回答很简单而且很重要——我在谷歌上也找不到这个,但在 php cmets 中我注意到有些人使用@sysmbol,为什么?以及它是如何使用的
      • @ 是抑制可能出现的任何错误消息的错误抑制运算符。我不知道为什么在你没有看到代码的情况下看到的代码中使用了这个。
      • 很抱歉延迟回复,@ 用于 cmets。我看到很多。 //@brow_cow- 描述了一头牛...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-08-31
      • 1970-01-01
      • 2017-07-24
      • 2013-08-24
      • 2012-04-25
      • 2014-03-17
      • 2018-11-17
      相关资源
      最近更新 更多