1

PHP::SerializationはHTTP::Responseをシリアライズしようとするとエラーになります。

例を次に示します。ヒントはありますか?

#!/usr/bin/perl -w

use strict ;
use warnings ;
use LWP ; 
use PHP::Serialization qw(serialize unserialize); 


my $url = 'http://stackoverflow.com/' ; 
my $ua  = LWP::UserAgent->new() ;
my $page = $ua->get($url) ; 

print "HTML page is ". length($page)." bytes long.\n" ; 
print $page ; print "\n" ; 

my $buffer ; 
eval { $buffer = serialize($page); } ; die $@ if $@ ;    


open FH, '>stored.dat' or die "Cannot create store file $!" ; 
binmode FH ; 
print FH $buffer ; 
close FH ; 

実行すると、次のようになります。

HTML ページの長さは 30 バイトです。
HTTP::レスポンス=ハッシュ(0x901f110)
/usr/local/share/perl/5.10.1/PHP/Serialization.pm 行 454 の HASH 参照ではありません。

シリアライゼーション/デシリアライゼーションの実験をさらに進めて、FreezeThaw
パッケージを試しました。次のスニペットでわかるように、機能しますが、別の問題が発生しました。
再構築された (逆シリアル化された) オブジェクトには型がないため、そのメソッドを使用できません。
それは「非参照」なので、 私も「祝福」することはできません。

この問題にどのようにアプローチすればよいですか?

#!/usr/bin/perl -w

use strict ;
use warnings ;
use HTML::Parser ; 
use HTML::Form ; 
use HTTP::Response ; 
use LWP ; 

use FreezeThaw qw(freeze thaw cmpStr safeFreeze cmpStrHard);

my $url = 'http://stackoverflow.com/' ; 
my $ua  = LWP::UserAgent->new() ;
my $page = $ua->get($url) ; 

print "HTML page is ". length($page)." bytes long.\n" ; 
print $page ; print "\n" ; 
print $page->status_line(), "\n" ; 

my $buffer ; 
eval { $buffer = freeze($page); } ; die $@ if $@ ;    

print "Serdes buffer is ". length($buffer)." bytes long.\n" ; 

open FH, '>stored.dat' or die "Cannot create store file $!" ; 
binmode FH ; 
print FH $buffer ; 
close FH ; 

my $otherb ; 
open FH, '<stored.dat' or die "Cannot open store file $!" ; 
binmode FH ; 
$otherb = do { local($/); <FH> } ; 
close FH ; 

print "Serdes buffer is ". length($otherb)." bytes long.\n" ; 

my $proto = HTTP::Response->new() ; 
my $recpg ; 

eval { $recpg = thaw ($otherb); } ; die $@ if $@ ; 

print $recpg ; 
#bless $recpg, ref($proto)||$proto ; 
bless $recpg, "HTTP::Response" ; 
print $recpg ; 

#print $recpg->status_line(), "\n" ; 

実行すると、次のようになります。

% ./serdesLab2.pl 
HTML page is 30 bytes long.
HTTP::Response=HASH(0x970ea10)
200 OK
Serdes buffer is 214347 bytes long.
Serdes buffer is 214347 bytes long.
Can't bless non-reference value at ./serdesLab2.pl line 45.
1% 
% 

可能な解決策をありがとう。

4

2 に答える 2

1

あなたがするとき

my $page = $ua->get($url); 

オブジェクトを取得していHTTP::Responseます。$response->content応答の内容を取得するには、メソッドを呼び出す必要があります。

my $response = $ua->get($url);
die "didn't get a page: ".$response->status_line."\n" unless $response->is_success;
my $page = $response->content;

エラー メッセージは、PHP::Serialize が単純な perl HASH/ARRAY ref (おそらくこの例では CODE ref) ではないものをシリアライズする方法を認識していないことを訴えています。

于 2012-06-28T01:29:29.503 に答える
0

HTTP::Responseおよび/またはHTTP::Requestオブジェクト(どれを思い出せないか)に_uriは、通常はURIであるメンバーがあります。そのオブジェクトは、祝福されたスカラー参照です。

エラーが報告された行を見回すと、PHP::Serializationすべてのオブジェクトがハッシュベースであると見なされているようです。したがって、祝福されたスカラー参照であるオブジェクトに遭遇すると、チョークします。

ノート:

=head1 TODO

さまざまなオブジェクト タイプをサポート

パッチを提案できるシリアライゼーション形式はわかりませんが、修正は次のようになります。

elsif ( $type eq 'obj' ) {
    my $class = ref($val);
    $class =~ /(\w+)$/;
    my $subclass = $1;

    my $reftype = reftype $val;
    if ($reftype eq 'HASH') {
        # blessed hash serialization
    }
    elsif ($reftype eq 'ARRAY') {
        # blessed array serialization
    }
    elsif ($reftype eq 'SCALAR') {
        # blesssed scalar serialization
    }
    elsif ($reftype eq 'CODE') {
        # blessed coderef serialization
    }
    elsif ($reftype eq 'GLOB') {
        # blessed globref serialization
    }
    else {
        # etc etc
    }

どこreftypeから来るScalar::Util。実際、サポートされていない型に遭遇したときに鳴らすだけであれば、これらのブランチを埋めたり、これをディスパッチテーブルに変えたりすると便利です。

于 2012-06-28T01:41:55.027 に答える