Hallo Community,
ich schreibe derzeit an einer Software, die unter anderem den Benutzern den Upload von Bild- und Textdateien, sowie das Ausfüllen einiger Formularfelder ermöglicht (es geht um das "Anlegen" von Experimentdaten aus einem Genlabor).
Das Script nutzt CGI, CGI::SESSION und schickt die POST-Parameter an sich selbst.
Nun habe ich folgendes Problem:
sub newMap {
my ($dbid,$dbsname,$dblname,... etc.etc
my $obj = {
dbmapid => $dbid,
dbmapshortname => $dbsname,
dbmaplongname => $dblname,
...
...
Dieses Objekt wird durch das Klicken eines Buttons erzeugt und die entsprechenden Formulardaten dort eingetragen. Anschließend wird dieses Objekt in ein Array hinterlegt und die Referenz in der Session gespeichert.
Dieses Verfahren funktioniert solange gut, bis die cgi->filefields ins Spiel kommen. Dann kann man zwar noch einmal ein Objekt erzeugen, danach aber nicht wieder. Der Grund ist folgender:
Wenn man sich den Inhalt des Objektes mit DATA::DUMPER ansieht, dann findet man in den FileField-Hashes folgendes:
'dbmapimage' => bless( \*{'Fh::fh00001blablabla.jpg'}, 'Fh' )
'dbmapthumb' => bless( \*{'Fh::fh00002blablablawasanders.jpg'}, 'Fh' )
'dbmapdatafile' => bless( \*{'Fh::fh00003blablabla.txt'}, 'Fh' )
Offensichtlich wird hier nicht nur der Dateiname von den Filefields zurückgegeben, sondern eine Referenz zu einem Typeglob-Objekt (Referenzen zu Filehandles werden durch Referenzen zu einem Typeglob erzeugt). Das "im Prinzip" ein Fh zurückgeben wird, ist kein Problem und durchaus auch erwünscht.
Der Upload funktioniert aber nur EINMALIG.
Wenn ich dann aber ein weiteres Objekt erzeugen will (das Formular ist dasselbe), dann kriege ich folgende Fehlermeldung:
Do not know how to reconstitute blessed object of base
type GLOB at /usr/share/perl5/CGI/Session.pm line 687
Ein bißchen Schnüffeln brachte folgendes in der CGI::SESSION::SERIALIZE::DEFAULT zutage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
sub __scan {
for (@_) {
if (blessed $_) {
if (overload::Overloaded($_)) {
my $r = reftype $_;
if ($r eq "HASH") {
$_ = bless { %$_ }, ref $_
} elsif ($r eq "ARRAY") {
$_ = bless [ @$_ ], ref $_
} elsif ($r eq "SCALAR" || $r eq "REF") {
$_ = bless \do{my $o = $$_},ref $_
} else {
croak "Do not know how to reconstitute blessed object of base type $r";
}
} else {
bless $_, ref $_
}
}
}
}
Dieser Codeabschnitt erklärt gut, warum der Vorgang nur einmal funktioniert: Zunächst ist der Fh !blessed und er wird geblesst (else-Fall). Beim zweiten Durchgang durch das Formular findet er offensichtlich nach dem POST ein bereits geblesstes Objekt (vermutlich drei, für jedes FileField der ersten Eingabe) und es kommt zu der in der ($r eq else) stehenden Fehlermeldung.
Daher ist meine Frage: Wie kriege ich das Formular in dem Sinne gelöscht, das die Uploadfields nach dem Upload wieder "wie neu", also "clean" ohne blessed-Objekte sind? Wie zerstöre ich das Objekt dahinter (DESTROY?)?.
Vielen Dank für Eure Hilfe!
PS: Noch folgende, wirklich nicht böse gemeinten, Anmerkung:
Bitte keinen Verweis auf irgendwelche Standard-Tutorials und Upload.cgi's -> über dieses Stadium bin ich etwas hinaus ;)