Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在PHP中反序列化Perl Data::Dumper输出_Php_Perl_Serialization_Data Dumper - Fatal编程技术网

如何在PHP中反序列化Perl Data::Dumper输出

如何在PHP中反序列化Perl Data::Dumper输出,php,perl,serialization,data-dumper,Php,Perl,Serialization,Data Dumper,我在Perl中有一个导出变量的结果,如下字符串: $VAR1 = { 'guard' => undef, 'work_hand' => undef, 'images' => {'1' => { 'mini_height' => 150, 'width' => 150, 'extension' => 'jpg',

我在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中反序列化这些数据

p.S.我在数据库中已经有这种格式的数据,我无法将其更改为json或其他格式。

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


JSON文档和示例可以在

上找到,如果您可以更改Perl代码,那么就使用一些标准的序列化格式,例如或,您可以在PHP中反序列化这些格式

即使你真的想,你也可以,尽管我一般不建议这样做。(下一次要在Python中反序列化相同的数据时该怎么办?)

如果您不能更改Perl代码,那么您只需咬紧牙关,尝试用PHP解析输出。我找不到任何现有的代码来实现这一点,所以看起来您可能需要编写自己的代码。虽然格式(通常)足够简单,您可以直接手工编写,但这可能是一项工作


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

既然您声明无法更改格式:

我不喜欢使用eval,但是因为您的语法非常接近预期的PHP数组语法,所以我认为我们可以顺其自然

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

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

<?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);
注意:我建议您现在花点时间改进并升级数据库内容,使其成为更标准的格式,因为这样以后更易于维护


您可以在数据库中循环,逐行获取所有内容,然后将数据运行到上面的函数中,并将其包装在
json\u encode()
中,并使用新的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] => 
)

这就是你想要的吗?

你有很多建议试图以这种或那种方式解析它,但真正的问题是为什么

为什么不让一个小的Perl程序加载它,并输出一个等价的JSON字符串呢

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

或者(更好的是)对整个数据库批量运行它,以从数据库中去除特定于Perl的数据格式;然后就可以使用PHP的标准JSON函数了


这将使PHP代码(或以后需要读取数据的任何其他语言)的使用变得更加简单。

显而易见且唯一可靠的解决方案是使用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);
}
//以Perl的Data::Dumper格式接收输入并生成PHP对象输出
函数perl_dd_to_php($dd_输出){
$process=proc_open(“perl-000-MJSON-e‘print encode_json eval’”,
阵列(阵列(“管道”、“r”)、阵列(“管道”、“w”),
$管道);
fwrite($pipes[0],$dd_输出);
fclose($pipes[0]);
$json_string=stream_get_contents($pipes[1]);
fclose($pipes[1]);
返回json_解码($json_字符串);
}

我将数据序列化为通用标准,例如,而不是您使用的任何格式(我猜是data::Dumper)。您确定是指“序列化”而不是“反序列化”吗?以特定于语言的序列化格式保存数据是一个错误的做法。经验教训:始终使用标准,即使你认为自己不需要标准。不是很好的序列化格式。如果输入中的任何字符串包含大括号或字符串
undef
,则可能会产生令人惊讶的结果。(对于后者,在
eval
之前执行
define('unde',null);
可能更容易、更安全)(此外,您真的必须在答案中同时包含原始字符串的副本和
print\r
输出吗?如果删除它们,我会给您+1。)为了可读性,截断了上面的内容。我喜欢你关于定义的观点,这是一个很好的建议。现在正在处理正则表达式,以解决字符串中出现
{}
的问题。您可以使用类似于
“array(#{\n“
”)}\n“
的内容替换它们,然后循环输出以撤消替换。(通过在替换中包含
{
}
,编码实际上也应该是完全可逆的。)我考虑过这一点,但为了简单性和代码认知,我想避免第二次替换循环。这是显而易见且唯一健壮的解决方案。它也比使用eval更安全
// 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);
}