http://qs321.pair.com?node_id=545924

lepetitalbert has asked for the wisdom of the Perl Monks concerning the following question:

Hello Dear Monks

I have this form :

<FORM ACTION="/hs/scripts/test1.pl" METHOD="post" ENCTYPE="multipart/f +orm-data"> Photo to Upload: <INPUT TYPE="file" NAME="pic1"> <br><br> <INPUT TYPE="submit" NAME="Submit" VALUE="Submit Form"> </FORM>

and the script :

#!/usr/bin/perl -w use strict; use warnings; use CGI; use CGI::Carp qw/fatalsToBrowser/; use Storable; my %db; my $query = new CGI; my $dbfile = "C:/Program Files (x86)/Abyss Web Server/htdocs/hs/script +s/db1"; print "Content-type: text/html\n\n"; my $var = $query->param("pic1"); print $var . "<br>"; # my @TMP1 = split ( // , $var); # $var = join ( "" , @TMP1); $db{"1"}{"pic1"} = $var; store \%db, $dbfile ;


which produces

pic.jpg Software error: Can't store GLOB items at ..\..\lib\Storable.pm (autosplit into ..\..\ +lib\auto\Storable\_store.al) line 215, at test1.pl line 25 For help, please send mail to this site's webmaster, giving this error + message and the time and date of the error.


if I uncomment

# my @TMP1 = split ( // , $var); # $var = join ( "" , @TMP1);


it works


But I have no idea why !


Thanks


Have a nice day.


"There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates

Replies are listed 'Best First'.
Re: CGI and Storable : explain me this, please.
by aufflick (Deacon) on Apr 27, 2006 at 01:58 UTC
    GLOB is a type of Perl variable (also known as a typeglob) that is a reference to a value in Perl's symbol table. If you want to know more about them you might want to read The Perl You Need To Know - Part 3.

    GLOB variables can't be serialised by Storable because it is a pointer to a table that is part of the current Perl runtime. If it was saved and restored, the symbol table in memory would not be the same one and it would not be able to point to the same entry. (Did that even make sense?! I hope so, it's a little tricky to explain).

    The question here, though, is why CGI's param method is returning a typeglob. Possibly the method performs differently in a string context?

    I notice that the form variable you are referencing is called pic1 - is the form a multipart file upload form? If so it makes more sense since CGI is probably giving you a filehandle to an open file that you will then have to do something with (like reading it into memory, copying it to a file etc.).

      The question here, though, is why CGI's param method is returning a typeglob. Possibly the method performs differently in a string context?
      ...
      CGI is probably giving you a filehandle...
      That is it -- See (directed at OP) the 'CREATING A FILE UPLOAD FIELD' section in the CGI docs .. When the form is processed, you can retrieve the entered filename by calling param():
      $filename = param('uploaded_file');
      The filename returned is also a file handle.

      So the split //, $var works because it's scalar context so is the filename.. Otherwise it must be treating it as a handle, and hence the observed error..
Re: CGI and Storable : explain me this, please.
by rhesa (Vicar) on Apr 27, 2006 at 02:37 UTC
    The quick fix is:
    # CGI returns the filename and the filehandle in the same variable, gi +ving the # name when treated as a string, and the handle otherwise. Therefore w +e need # to stringify $var explicitly, because Storable can't store a filehan +dle. $db{"1"}{"pic1"} = "$var";
    I suggest you leave the comment in place, because it's a pretty unusual circumstance.

      Hi Monks

      Yes I'm uploading 3 pics.

      this works

      $db{"1"}{"pic1"} = "$var";

      Thanks

      The code is

      for ($i=1; $i < 4; $i++) { $tmp = "pic" . $i; my $filename = $query->param($tmp); $db{$n}{$tmp} = "$filename"; $upload_filehandle = $query->upload($tmp); open UPLOADFILE, ">$upload_dir/$filename"; binmode UPLOADFILE; while ( <$upload_filehandle> ){ print UPLOADFILE; } close UPLOADFILE; } store \%db, $dbfile ;


      Thanks

      Have a nice day

      "There is only one good, namely knowledge, and only one evil, namely ignorance." Socrates
      i'd guess that scalar $var instead of "$var" would work, too .. dunno (don't think i personally have a preference, though maybe some people would) which is "better" (assuming the former works)

      Update: see below

        Why would being in scalar context stringify a value? A glob in scalar context is still a glob.