Community Documentation

Handling File Uploads

Last updated January 25, 2010. Created by AlexisWilke on January 22, 2007.
Edited by nicksanta, add1sun, Darren Oh, bradlis7. Log in to edit this page.

In order to use file uploads with the Form API, you will have to include the following in your form:

<?php
$form
['#attributes'] = array('enctype' => "multipart/form-data");
?>

You can then handle the upload with file_check_upload. Here's an example:

<?php
function form() {
 
$form['#attributes'] = array('enctype' => "multipart/form-data");
 
//'upload' will be used in file_check_upload()
 
$form['upload'] = array('#type' => 'file');
}

function
form_validate() {
  if(!
file_check_upload('upload')) {
   
// If you want to require it, you'll want to do it here... something like this:
   
form_set_error('upload', 'File missing for upload.');
  }
}

function
form_submit() {
 
$file = file_check_upload('upload');
 
//handle the file, using file_save_upload, or something similar
}
?>

Comments

This should work alright(at least in 4.7)

function render_form() {

// Form:
$form['new']['upload'] = array('#type' => 'file', '#title' => t('Upload image'), '#size' => 40);
$form['new']['attach'] = array('#type' => 'submit', '#value' => t('Upload'));
$form['#attributes']['enctype'] = 'multipart/form-data';

$output = drupal_get_form('render_form', $form);
return $output;
}

print render_form();

function render_form_submit($form_id, $form_values) {

// Submit hook:
# if ($op == t('Upload')) {   
    $dir = variable_get('file_directory_path', NULL); //file_create_path('files/badges'); If you want your files in a new directory
    $is_writable = file_check_directory($dir, 1);
    if($is_writable) { 
      $source = file_check_upload('upload');     
      // Security measure to prevent exploit of file.php.png
      $source->filename = upload_munge_filename($source->filename);
      
      if ($file = file_save_upload($source,$dir )) {
        if (image_get_info($file->filepath)) {
          drupal_set_message(t('New image saved.'));
        } else {
          file_delete($file->filepath);
          drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
        }
      }
    }

  #}
 
}

Tree Style Forms

I'm not 100% about this, but with Drupal 5.1 it seems that if your form looks like this:

<?php
function form() {
 
$form['#attributes'] = array('enctype' => "multipart/form-data");
 
 
$form['itemone']['itemtwo']['upload'] = array(
   
'#type' => 'file');
  ...

  return
$form
}
?>

...then you need to pass "itemone" to file_check_upload(), rather than "upload" as you may be expecting.

Addition to the way drupal 5.x does file uploads.

You are correct coofercat. This is how I managed to get around that by using static text in a naming scheme such as $form['upload_1'], $form['upload_2'], etc...

  if($is_writable)
  {
    // loop through each of the upload items
    foreach($form_values as $key=>$data)
    {
      //print "Key: $key<br/>";

      if(strpos($key, 'upload') !== FALSE) // MAKE SURE WE ARE IN A KEY FOR AN UPLOAD
      {
        $source = file_check_upload($key);
       
        print "<pre>" . print_r($source, TRUE) . "</pre>";
        // Security measure to prevent exploit of file.php.png
        $source->filename = upload_munge_filename($source->filename);
           
        if ($file = file_save_upload($source,$dir ))
        {
          if (image_get_info($file->filepath))
          {
            drupal_set_message(t('New image saved.'));
          }
          else
          {
            file_delete($file->filepath);
            drupal_set_message('Uploaded file does not appear to be a valid image file. Please try again.');
          }
        }
      }
    }
  }

Hope this helps anyone looking for file upload info as well.

Anthony Wlodarski
PHP/MySQL Developer
www.thrillist.com
560 Broadway, Suite 308
New York, NY 10012
p 646.274.2435
f 646.557.0803

Come on!

It has been more than THREE YEARS since someone noticed this awful behaviour on Drupal 5! And it's still present on 6? That's just ridiculous.

Still not fixed...

Seems people even tried to provide a patch but the patch failed the tests. Sad that this is still an issue.

A slightly more complete

A slightly more complete example found here: http://drupal.org/node/85922

Also, if you are associating this file with a custom node type, you may want to use file_save_upload() in your hook_insert() function when the fully populated node object is available. This is good for saving the file with a unique name and/or saving that new file name to your custom content type's table.

Be well,
R.J. Steinert III
RjSteinert.com

"Happiness is the process not the place."
-Diener

file_check_upload() does not

file_check_upload() does not exist in Drupal 6.x

Example using Drupal 6 BUT not enought: module alternative

Yes, it has been cleared from Drupal 6.

I've found a working example using Drupal 6:
http://thedrupalblog.com/uploading-file-forms-api-and-attaching-it-email

You have to use file_save_upload. Continuing the example of this page:

$fieldName = 'upload';
if (isset($_FILES['files']) && is_uploaded_file($_FILES['files']['tmp_name'][$fieldName])) {
    // attempt to save the uploaded file
    $file = file_save_upload($fieldName);

    // set error if file was not uploaded
    if (!$file) {
      form_set_error($fieldName, 'Error uploading file.');
      return;
    }
       
    // set files to form_state, to process when form is submitted
    $form_state['values']['file'] = $file;
}

(code borrowed from the above link)

As you see you may check if file was uploaded using first if sentence.

$fieldname is set to 'upload' because is the name used in the $form definition in the example.

BUT uploaded file info is lost if validation fails. Not a funny thing. To avoid that you must track file info with $_SESSION PHP var. Luckily, there's a module that does that:

http://drupal.org/project/upload_element

The same funcionality is included in D7, so only needed for D6.

In Drupal 6.x you can use

In Drupal 6.x you can use http://api.drupal.org/api/function/file_save_upload/6

Déja Augustine

A note should be added that,

A note should be added that, file uploads should be stored in a subdirectory under drupal's main files directory, for security reasons.

enctype

Note that as of Drupal 7 the Form API automatically sets the enctype="multipart/form-data", so you don't have to.

--Andy
Developing Drupal websites for Livelink New Media

Page status

Log in to edit this page

About this page

Drupal version
Drupal 5.x

Archive

Drupal’s online documentation is © 2000-2013 by the individual contributors and can be used in accordance with the Creative Commons License, Attribution-ShareAlike 2.0. PHP code is distributed under the GNU General Public License. Comments on documentation pages are used to improve content and then deleted.