как я могу сохранить объект в сеансе perl

У меня есть объект Emp (класс) с полями name, id и password:

$emp = new Emp({name=>'pavan', id=>101, password=>'05cc11'});

$serializble = freeze($emp);

Сохранение в сеансе:

$session->param("emp",$serializble);

Но когда я открываю объект сеанса, который хранится в каталоге tmp, значение emp равно undef.

Обновлять

Обновлено после использования Storeable для сериализации объекта.

$serializble = freeze($emp);

$session->param("emp",$serializble);

это файл сеанса (с добавленными разрывами строк для удобства чтения):

$D = {'_SESSION_ID' => 'dd75c6042893334a6bf26794b4ce5c74',
'_SESSION_ATIME' => 1356628765,
'emp' => '^D^G^D1234^D^D^D^H^Q^CPEmp^C^B^@^@^@ ^Epavan^D^@^@^@name^H�^B^@^@^@id',
'_SESSION_REMOTE_ADDR' => '127.0.0.1',
'_SESSION_CTIME' => 1356628765};;$D

Когда я пытаюсь вернуть объект из сеанса, он возвращает undef:

$recoverable = thaw($session->param('emp');

print $recoverable; 

вот мой общий код

Класс Emp:

package Emp;

sub new{
    my ($class, $args) = @_;

    my $self = bless{}, $class;

    $self->{name} = $args->{name};
    $self->{id}=$args->{id};

    return $self;
}

sub getEmpname{
    my $self = shift;
    return $self->{name};
}

1;

emp.cgi

$query = new CGI();

$session = new CGI::Session("driver:File", undef, {Directory => "/tmp"});

$emp = new Emp( { name => $query->param('username'),
                  id   => 101
                } );
my $serialized = freeze($emp);

$session->param("emp", $serialized);

$login = $emp->getEmpname();  #it is the method of Emp class

$cookie  = $query->cookie( -name    => $login,
                           -value   => $session->id,
                           -expires => '+3M',
                         );

print $query->header( -type    => 'text/html',
                      -cookie  => $cookie,
                    );

welcome.cgi

$q = new CGI();
   
$sid = $q->cookie('login') || $q->param('login') || undef;
  
$session = new CGI::Session(undef, $sid, {Directory=>'/tmp'});
  
print $q->header('text/html');
print $q->start_html('title');
print "<br>";
print Dumper $session->param('emp');
my $emp = thaw( $session->param('emp') );  //which is saved in session object.
print $emp->getEmpname();
print end_html;

person pavan    schedule 27.12.2012    source источник
comment
Это объект сеанса, в котором хранится мой объект emp.   -  person pavan    schedule 28.12.2012


Ответы (1)


Вы не можете просто хранить объект там, где ожидается строка.

Если у нас есть объект $o класса Emp и предполагается, что этот объект реализован с использованием хэшей, тогда строковое определение этого объекта будет примерно таким, как Emp=HASH(0x9bc8880). Информация, включенная в эту строку, не позволяет восстановить объект из этой строки.

Вместо этого вам нужно выбрать сериализацию объекта, чтобы вы могли восстановить объект.

Модуль Data::Dumper сериализует структуры данных в виде кода Perl, который можно evalобработать для воссоздания исходного значения. . Модуль Storable хранит данные в двоичном формате и может быть применим здесь.

Вы можете сериализовать структуру данных (или объект) через freeze и восстановить ее через thaw.

use strict; use warnings; use Storable qw(freeze thaw); use Data::Dumper;

my $o = bless {a => 1, b => 2}, 'Emp';

print "> Dumper representation of original ($o)\n";
print Dumper $o;
print "> serializing the object...\n";
my $serialized = freeze($o);
print "> restoring the object...\n";
my $restored = thaw($serialized);
print "> Dumper representation of copy ($restored)\n";
print Dumper $restored;

Выход:

> Dumper representation of original (Emp=HASH(0x8de78c8))
$VAR1 = bless( {
                 'a' => 1,
                 'b' => 2
               }, 'Emp' );
> serializing the object...
> restoring the object...
> Dumper representation of copy (Emp=HASH(0x8f5df64))
$VAR1 = bless( {
                 'a' => 1,
                 'b' => 2
               }, 'Emp' );

или подобное. Обратите внимание, что восстановленный объект имеет другую ячейку памяти, но в остальном эквивалентен.

Если вы хотите сериализовать структуру данных в файл, вы можете вместо этого использовать store и retrieve; обратитесь к документации для дальнейших примеров.

person amon    schedule 27.12.2012
comment
теперь он сериализован и хранится в файле сеанса (отредактировано в вопросе), но когда я возвращаю объект из сеанса, возвращается undef - person pavan; 27.12.2012
comment
@pavan Я сам не использую CGI::Session, но документы интересны. В частности, new и load позволяют вам выбрать Storable в качестве сериализатора вместо Data::Dumper (который вы, похоже, используете). Это, вероятно, позволит обойти проблемы с кодировкой, которые у вас могут возникнуть (хотя у этих почтенных модулей не должно быть никаких проблем). Однако все, что я могу сделать, это гадать, пока мы не увидим больше вашего кода. - person amon; 28.12.2012
comment
@pavan Я прочитал ваш код, но не могу отладить ваши проблемы (я любитель, а не платный консультант). Обязательно use strict; use warnings; use CGI::Carp qw(fatalsToBrowser); при отладке скриптов CGI. Не используйте глобальные переменные (особенно под mod_perl). Посмотрите на метод класса load вместо метода new для загрузки сеанса. Проверьте возвращаемые значения load и thaw. Может быть, задайте новый вопрос с большим акцентом на CGI::Session и меньше на сериализацию, которую я рассмотрел здесь. - person amon; 28.12.2012
comment
я, наконец, получил решение, когда восстановил объект с помощью оттепели, он должен быть благословлен $emp = bless{$emp},Emp; - person pavan; 17.01.2013