6

我在 Perl 中有一个导出变量的结果,如下所示:

$VAR1 = {
    'guard' => undef,
    'work_hand' => undef,
    'images' => 
        {'1' => 
            {
            'mini_height' => 150,
            'width' => 150,
            'extension' => 'jpg',
            'filename' => 'object_1.1330907414.96873.jpg',
            'mini_width' => 150,
            'class' => 'Ontico::Image',
            'height' => 150,
            'mini_filename' => 'object_1.1330907414.96873.mini.jpg',
            'size' => 26053,
            'symname' => 'big_logo'
            },
        '2' => 
            {
            'width' => 48,
            'extension' => 'jpg',
            'alt' => 'Даниэле Галлоппа',
            'height' => 48,
            'mini_filename' => 'object_91.1235312905.mini.jpg',
            'size' => 12809,
            'symname' => 'logo',
            'mini_height' => 150,
            'filename' => 'object_91.1235312905.jpg',
            'mini_width' => 150,
            'class' => 'Ontico::Image'
            }
        },
        'show_league_banner' => 0,
        'back_hand' => undef,
        'weight_category' => undef,
        'stick_position' => undef
    };

如何在 PHP 中反序列化这些数据?

PS 我已经在 DB 中有这种格式的数据,我不能将其更改为 json 或其他格式。

4

6 回答 6

5

您有很多建议尝试以一种或另一种方式解析它,但真正的问题是为什么?

为什么不只用一个小的 Perl 程序来加载它,然后输出一个等效的 JSON 字符串。

然后,您可以在 PHP 中调用该 Perl 程序来进行转换;这意味着您正在使用 Perl 来读取 Perl 格式,这将保证正确的转换。

或者(更好的是)对整个数据库批量运行它,以摆脱数据库中特定于 Perl 的数据格式;那么你可以只使用 PHP 的标准 JSON 函数。

这样一来,您的 PHP 代码(或您以后需要用来读取数据的任何其他语言)中的生活就会变得如此简单。

于 2012-09-10T14:20:55.500 回答
4

显而易见且唯一可靠的解决方案是使用 Perl 将输入反序列化并重新序列化为标准格式。可以完成这项任务的 Perl 程序也不需要很大。

// receive input in Perl's Data::Dumper format and produce PHP object output
function perl_dd_to_php( $dd_output ) {
    $process = proc_open( "perl -000 -MJSON -e 'print encode_json eval <>'",
                          array( array("pipe","r"), array("pipe","w") ),
                          $pipes );
    fwrite($pipes[0], $dd_output );
    fclose($pipes[0]);

    $json_string = stream_get_contents($pipes[1]);
    fclose($pipes[1]);

    return json_decode($json_string);
}
于 2012-09-10T14:35:28.230 回答
3

由于它不是 JSON,但它看起来像 JSON,您可以尝试修改 JSON 库以使用该格式。我使用了这个JSON 库,替换:=>并添加undef,如您在此处看到的(第 496、671 和 681 行)。这非常简单,真的,我假设您可以以类似的方式解决其他差异。

结果是:

stdClass Object
(
    [guard] => 
    [work_hand] => 
    [images] => stdClass Object
        (
            [1] => stdClass Object
                (
                    [mini_height] => 150
                    [width] => 150
                    [extension] => jpg
                    [filename] => object_1.1330907414.96873.jpg
                    [mini_width] => 150
                    [class] => Ontico::Image
                    [height] => 150
                    [mini_filename] => object_1.1330907414.96873.mini.jpg
                    [size] => 26053
                    [symname] => big_logo
                )

            [2] => stdClass Object
                (
                    [width] => 48
                    [extension] => jpg
                    [alt] => Даниэле Галлоппа
                    [height] => 48
                    [mini_filename] => object_91.1235312905.mini.jpg
                    [size] => 12809
                    [symname] => logo
                    [mini_height] => 150
                    [filename] => object_91.1235312905.jpg
                    [mini_width] => 150
                    [class] => Ontico::Image
                )

        )

    [show_league_banner] => 0
    [back_hand] => 
    [weight_category] => 
    [stick_position] => 
)

那是你要找的吗?

于 2012-09-10T14:08:03.050 回答
1
use JSON;

(或任何其他数据交换格式,如 XML)

CPAN提供 JSON 文档和示例

于 2012-09-10T13:27:36.753 回答
1

如果您可以更改 Perl 代码,则按照 amon 的建议进行操作,并使用可以在 PHP 中反序列化的一些标准序列化格式,例如JSONXMLYAML 。

如果你真的想要的话,你甚至可以让 Perl 输出 PHP 的原生序列化格式,尽管我通常不建议这样做。(当你接下来想在 Python 中反序列化相同的数据时呢?)

如果您无法更改 Perl 代码,则只能硬着头皮尝试在 PHP中解析Data::Dumper输出。我找不到任何现有的代码来做到这一点,所以看起来你可能必须自己编写。这可能是解析器生成器的工作,尽管格式(通常)足够简单,您可能只需手动编码即可。


编辑:既然你说你在数据库中有这个序列化数据,为什么不写一个Perl程序来读取数据并将其转换为更标准的序列化格式,如 JSON?

于 2012-09-10T13:56:39.367 回答
0

既然你说你不能改变格式:

我不喜欢使用 eval,但是因为您的语法与预期的 PHP 数组语法非常接近,所以我认为我们可以让它滑动。

设置$string等于数据库中符合以下格式的内容。请参阅下面的使用您提供的数据的工作示例。在一天结束时,PHP 会将 perl var 开头的变量设置为新的解析数组。

由于它将是一个文本块/大字符串,请执行以下操作:

<?php
$string = "\$VAR1 = {
    'guard' => undef,
    'work_hand' => undef,
    'images' =>
        {'1' =>
            {
            'mini_height' => 150,
            ... // truncated for readability
    };";

$res = str_replace(array("{", "}", 'undef'), array("array(", ")", "''"), $string);

eval($res);

print_r($VAR1);

你的结果是:

Array
(
    [guard] =>
    [work_hand] =>
    [images] => Array
        (
            [1] => Array
                (
                    [mini_height] => 150 ...

注意:我建议您现在花时间将数据库内容改造和升级为更标准的格式,只是因为将来更容易维护。

您可以遍历数据库,逐行获取所有内容,然后将数据运行到上面的函数中,然后将其包装json_encode()并使用新的 JSON 字符串更新数据库行。这将使您在未来免于头疼,并允许您为新标准更新所有数据。

于 2012-09-10T13:56:45.317 回答