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

何らかの方法で解析するための提案がいくつかありますが、本当の問題はその理由です。

それをロードし、同等の JSON 文字列を吐き出す小さな Perl プログラムを用意してみませんか。

次に、PHP 内からその Perl プログラムを呼び出して変換を行うことができます。これは、Perl 形式を読み取るために Perl を使用していることを意味し、正しい変換が保証されます。

または (できれば) データベース全体に対してバッチで実行し、DB から 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 に答える
1
use JSON;

(または XML のような他のデータ交換形式)

JSON のドキュメントと例は、CPANで入手できます。

于 2012-09-10T13:27:36.753 に答える
1

Perl コードを変更できる場合は、amon の提案に従って、PHP で逆シリアル化できるJSONXML、またはYAMLなどの標準的なシリアル化形式を使用してください。

私は一般的にはお勧めしませんが、どうしてもやりたければ、Perl で PHP のネイティブなシリアル化形式を出力するようにすることもできます。(次に同じデータを Python などで逆シリアル化したい場合はどうしますか?)

Perl コードを変更できない場合は、我慢して、 Data::Dumperの出力を PHP で解析してみるしかありません。それを行うための既存のコードが見つからなかったので、独自に作成する必要があるようです。これはパーサー ジェネレーターの仕事になる可能性がありますが、形式は (通常) 単純なので、ハンドコーディングするだけで済みます。


編集:データベースにこのシリアル化されたデータがあると言うので、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 に答える