【问题标题】:Unable to recreate object from var_exported data (in PHP)无法从 var_exported 数据重新创建对象(在 PHP 中)
【发布时间】:2012-01-22 15:26:49
【问题描述】:

在我们的实时服务器上运行的脚本从以下行发送数据:

$log_output .= '<br>'.__LINE__.'<br>recordings_data='.var_export($recordings_data,TRUE);

看起来像这样:

recordings_data=stdClass::__set_state(array('RecordingLongResponse' => 数组 ( 0 => stdClass::__set_state(...), 1 => stdClass::__set_state(), 2 => stdClass::__set_state(), 3 => stdClass::__set_state(array('roomStartDate' => '1321977120000', 'roomEndDate' => '1321977120000', 'recordingURL' => 'serverURL1', 'secureSignOn' => 假,'recordingId' => '1287268130290', 'creationDate' => '1321977120000', 'recordingSize' => '6765975', 'roomName' => '利益相关者分析', 'sessionId' => '1287268130229', )), ...), ))

我不确定如何“重新创建”对象。我尝试反序列化它:

 $recording_data_ser= file_get_contents('elm-ser-data.txt'); // where I've saved everything after the '='
 $recording_data = unserialize($recording_data_ser);

【问题讨论】:

    标签: php serialization deserialization


    【解决方案1】:

    如果您在stdClass 的实例上调用var_export(),它会尝试使用::__set_state() 导出它,由于某种原因,stdClass 中没有实现。

    但是,将关联数组转换为对象通常会产生相同的效果(至少在我的情况下是这样)。所以我写了一个improved_var_export() 函数来将stdClass 的实例转换为(object) array () 调用。如果您选择导出任何其他类的对象,我建议您在这些类中实现 ::__set_state()

    <?php
    /**
     * An implementation of var_export() that is compatible with instances
     * of stdClass.
     * @param mixed $variable The variable you want to export
     * @param bool $return If used and set to true, improved_var_export()
     *     will return the variable representation instead of outputting it.
     * @return mixed|null Returns the variable representation when the
     *     return parameter is used and evaluates to TRUE. Otherwise, this
     *     function will return NULL.
     */
    function improved_var_export ($variable, $return = false) {
        if ($variable instanceof stdClass) {
            $result = '(object) '.improved_var_export(get_object_vars($variable), true);
        } else if (is_array($variable)) {
            $array = array ();
            foreach ($variable as $key => $value) {
                $array[] = var_export($key, true).' => '.improved_var_export($value, true);
            }
            $result = 'array ('.implode(', ', $array).')';
        } else {
            $result = var_export($variable, true);
        }
    
        if (!$return) {
            print $result;
            return null;
        } else {
            return $result;
        }
    }
    
    // Example usage:
    $obj = new stdClass;
    $obj->test = 'abc';
    $obj->other = 6.2;
    $obj->arr = array (1, 2, 3);
    
    improved_var_export((object) array (
        'prop1' => true,
        'prop2' => $obj,
        'assocArray' => array (
            'apple' => 'good',
            'orange' => 'great'
        )
    ));
    
    /* Output:
    (object) array ('prop1' => true, 'prop2' => (object) array ('test' => 'abc', 'other' => 6.2, 'arr' => array (0 => 1, 1 => 2, 2 => 3)), 'assocArray' => array ('apple' => 'good', 'orange' => 'great'))
    */
    
    // Example implementation in context of OP
    $export = improved_var_export($data, true);
    file_put_contents(dirname(__FILE__).'/data.php', '<'.'?php return '.$export.'; ?'.'>');
    
    // "Unserialization" (evaluation)
    $import = include dirname(__FILE__).'/data.php';
    ?>
    

    【讨论】:

      【解决方案2】:

      var_export() 旨在将数据结构转储到文件中。然后,您必须 eval()include()require() 该文件。 serialize() 格式与 var_export 完全不同。

      var_export 生成有效的 PHP 代码来定义数据结构,就像您自己写出数组/对象定义一样。序列化/反序列化以完全不同的格式写出,它们不可互换。

      【讨论】:

        【解决方案3】:

        serialize()unserialize() 是普遍接受的转储/加载 PHP 对象的方法。您也可以使用json_encode()json_decode() 来实现。你有什么理由要使用var_export()吗?

        编辑:您只能unserialize() serialize() 的结果 - var_dump() 的格式完全不同,并且不是为导入而设计的,除非您使用 eval()

        例如:

        $arr = array('foo' => 'bar');
        
        var_export($arr);
        #=> array (
        #=>  'foo' => 'bar',
        #=> )
        
        echo serialize($arr);
        #=> a:1:{s:3:"foo";s:3:"bar";}
        
        echo json_encode($arr);
        #=> {"foo":"bar"}
        

        获得序列化数据后(通过serialize()json_encode()),您可以使用相反的方法(分别为unserialize()json_decode())重新创建对象。

        【讨论】:

        • +1。你去吧。我之前评论过,因为我认为这只是另一个 BOM 问题,但我只是看到了 OP 在做什么。 :)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-10-06
        • 1970-01-01
        • 1970-01-01
        • 2017-05-07
        • 2018-07-15
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多