Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw

Uploading files: can't find contents?

by ezekiel (Pilgrim)
on Apr 04, 2003 at 00:39 UTC ( #247937=perlquestion: print w/replies, xml ) Need Help??

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

Hello all

I have a CGI script where a user indicates the location of an XML file on the file system through a form. On submission, the script should upload the file and store it in a database. At present, it seems to get all the correct information from the form but doesn't get the contents of the file. Here is what I have so far:

The relevant HTML form:

<p> Upload the file: <input type="file" name="upload_file"> </p>

The part of the code to get the file:

my $filename = $this->cgi()->param('upload_file'); my $xml = _upload_file($filename); sub _upload_file { my $filename = shift; my $file_contents = ""; my $buffer; while ( read($filename, $buffer, 1024) ) { $file_contents .= $buffer; } return $file_contents; }

At a guess it is because the $filename does not contain the full path to the file? However, I've seen the same code work in another program as is (I just cut'n'pasted it!). Furthermore, if I do need the full path, how do I get it from the HTML form?


Replies are listed 'Best First'.
•Re: Uploading files: can't find contents?
by merlyn (Sage) on Apr 04, 2003 at 00:53 UTC
    Perhaps you should follow the advice of the manpage:
    When the form is processed, you can retrieve the entered filename by calling param(): $filename = $query->param('uploaded_file'); Different browsers will return slightly different things for the name. Some browsers return the filename only. Others return the full path to the file, using the path conventions of the user's machine. Regardless, the name returned is always the name of the file on the user's machine, and is unrelated to the name of the temporary file that creates during upload spooling (see below). The filename returned is also a file handle. You can read the contents of the file using standard Perl file reading calls: # Read a text file and print it out while (<$filename>) { print; } # Copy a binary file to somewhere safe open (OUTFILE,">>/usr/local/web/users/feedback"); while ($bytesread=read($filename,$buffer,1024)) { print OUTFILE $buffer; } However, there are problems with the dual nature of the upload fields. If you "use strict", then Perl will com- plain when you try to use a string as a filehandle. You can get around this by placing the file reading code in a block containing the "no strict" pragma. More seriously, it is possible for the remote user to type garbage into the upload field, in which case what you get from param() is not a filehandle at all, but a string. To be safe, use the upload() function (new in version 2.47). When called with the name of an upload field, upload() returns a filehandle, or undef if the parameter is not a valid filehandle. $fh = $query->upload('uploaded_file'); while (<$fh>) { print; } In an array context, upload() will return an array of filehandles. This makes it possible to create forms that use the same name for multiple upload fields. This is the recommended idiom.

    -- Randal L. Schwartz, Perl hacker
    Be sure to read my standard disclaimer if this is a reply.

      Actually he is explicitly following this advice merlyn (making the presumption that $this->cgi is a CGI object). No doubt he will be missing the ENCTYPE="multipart/form-data" in the FORM TAG or have uploads disabled $CGI::DISABLE_UPLOAD or be exceeding $CGI::POST_MAX.

      One of the less user friendly things about is that if misses the opportunity to report the cause of failing file uploads and leave a useful message in err_str()




        how could i access $CGI::DISABLE_UPLOAD ?
        #!/usr/bin/perl -w use CGI; print "CGI::DISABLE_UPLOADS: $CGI::DISABLE_UPLOADS\n";
        Name "CGI::DISABLE_UPLOAD" used only once: possible typo at cgi-bin/ line 3.
        Use of uninitialized value in concatenation (.) at cgi-bin/ line 3.
        thx maksl

        the other name variable gives CGI::POST_MAX: -1, perhaps my version of CGI can't disable upload?

        added plural to above, thx jasonk .. this results in CGI::DISABLE_UPLOADS: 0

Re: Uploading files: can't find contents?
by jasonk (Parson) on Apr 04, 2003 at 00:50 UTC

    You missed part of the relevant html that could be the problem, if your <form> tag doesn't contain ENCTYPE="multipart/form-data", you won't get the uploaded files.

    We're not surrounded, we're in a target-rich environment!

Log In?

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://247937]
Approved by VSarkiss
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (3)
As of 2023-06-05 00:04 GMT
Find Nodes?
    Voting Booth?
    How often do you go to conferences?

    Results (22 votes). Check out past polls.