#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    4
    Rep Power
    0

    Question Perl : Filehandles in 2D Array


    Oh man, I'm hoping someone out there might be able to help me out with this one.

    I've been sorta 'Frankensteining' some code together from an old script and some examples on the web in an attempt to get file attachments to work with a webform. The idea is that the site visitor is able to select multiple files from their computer, have them upload to a server and then have the script attach them to an email and send it off.

    The script worked great when there was just one file selected but I now need to have the 'multiple' option enabled in order for users to be able to (obviously) select multiple files for upload. When it was just one file, I ran a check to make sure the filename was valid and if it wasn't, it would rename it with only acceptable characters. This still appears to be working just fine with the FOR loop in here.
    Where I seem to be having the most problems is at the OPEN (UPLOAD FILE...) - for some reason it isn't reading the array values as proper filehandles but is instead simply injecting the filename as a string into the files. If I upload a Doc file, all I see is the name of the document inside the file.

    I would be forever grateful if someone were able to point me in the right direction on this. Thanks!


    This is the section of code that is giving me grief:


    Code:
    # ------ These are the modules used at the top of my script -----------
    use strict;
    use CGI;
    use CGI::Carp;
    use File::Basename;
    use MIME::Base64;
    use MIME::Lite;
    use MIME::Types qw(by_suffix by_mediatype import_mime_types);
    use Encode::Byte;
    use Captcha::reCAPTCHA;
    #---------------------------------------------------------------------------
    
    
    my $upload_dir = '\\MyDirectory\SubDirectory';
    my $filename_characters = 'a-zA-Z0-9_.-';
    
        my @upload;
    
        @upload[0] = [$q->param("Uploads")];    # set first row of 2D array to the webform filenames selected.
        @upload[1] = [$q->upload("Uploads")];   # set the second row of the 2D array to the webform filehandles
        
        for (my $i=0; $i<=$#{$upload[0]}; ++$i)
            {       
                # Validate file name and modify if needed
                my ($filename,undef,$ext) = fileparse($upload[0][$i],qr{\..*});
                
                # append extension to filename
                $filename .= $ext;
                # convert spaces to underscores "_"
                $filename =~ tr/ /_/;
                # remove illegal characters
                $filename =~ s/[^$filename_characters]//g;
                
                # satisfy taint checking
                if ($filename =~ /^([$filename_characters]+)$/) 
                    {
                        $filename = $1;
                    }
                else
                    {
                        error("The filename is not valid. Filenames can only contain these characters: $filename_characters")
                    }
            
                my ($mime_type, $encoding) = by_suffix($filename);  # Get file Mime Type and Encoding for the email attachement
                
                # Open file, write data to file, close file. 
                open (UPLOADFILE, ">$upload_dir/$filename") or error("Can't open/create \"$upload_dir/$filename\": $!");
                
                 #THIS IS WHERE I'M HAVING PROBLEMS
                binmode UPLOADFILE;
                while ( <$upload[1][$i]> ) {
                    print UPLOADFILE;
                }
                close UPLOADFILE;
        
            # Attach file to email            
            $msg->attach(        Type            =>$mime_type,
                                Path             =>"$upload_dir\\$filename",
                                Filename        =>"$filename",
                                Encoding        =>$encoding);
                                
            }  # Loop back for next file.
        
        $msg->send('smtp', 'smtp.server.com', Timeout=>30);
  2. #2
  3. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,938
    Rep Power
    1225
    Have you read this portion of the CGI documentation?
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,938
    Rep Power
    1225
    Do you understand the difference between these and when to use one or the other?

    @upload[0]

    $upload[0]
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    4
    Rep Power
    0
    Hmmm... apparently not.

    Thanks for the link. I think I found a solution though after all that frustration. I just tested assigning the array value to another variable before running the write.

    Something like this:

    Code:
    my $fh = $upload[1][$i];  # Set file handle to variable
    			
    	binmode UPLOADFILE;  # Write file to server
    	while ( <$fh> ) {
    		print UPLOADFILE;
    	}
    	close UPLOADFILE;
    I think I had tried @upload[1][$i] in previous attemps though my syntax may have been wrong at that time.

    Regardless - the struggle paid off.

    Thanks for the direction though!



    Originally Posted by FishMonger
    Do you understand the difference between these and when to use one or the other?

    @upload[0]

    $upload[0]
  8. #5
  9. No Profile Picture
    Contributing User
    Devshed Intermediate (1500 - 1999 posts)

    Join Date
    Apr 2009
    Posts
    1,938
    Rep Power
    1225
    but I now need to have the 'multiple' option enabled in order for users to be able to (obviously) select multiple files for upload
    You need to use separate input fields of type 'file', not a single dropdown where 'multiple' selection is enabled.
  10. #6
  11. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jan 2013
    Posts
    4
    Rep Power
    0
    Actually, I've been able to make this method working using
    Code:
    <input type="file" name="Uploads" id="uploadFile" multiple>
    as my webform input tag. It's not a drop down, but it allows the user to select as many files from a folder as they like.


    Originally Posted by FishMonger
    You need to use separate input fields of type 'file', not a single dropdown where 'multiple' selection is enabled.

IMN logo majestic logo threadwatch logo seochat tools logo