I have the following code in my form.

$form['new']['upload'] = array(
  '#type' => 'file',
  '#title' => t(''),
  '#size' => 40,

On the submission handler, it returns the file name but it does not save the file and return a file object. What else do I need to do?

What I am trying to do is create a block where you can upload a file that it is saved in a node's file field.


3 Answers 3


Take a look at file_save_upload() and the functions which call it.

The function will handle the validation of the file, and save it to a new location. In Drupal 7 this also adds the file to file_managed table.
Note that the file will be stored as a temporary file, so make sure to set the status of the file to permanent afterwards.

You will probably want to implement the file_save_upload function inside your form's validation hook (before the submit handler), so you can alert the user if the file upload failed, or did not meet your validation requirements.

If the name of the image field you are trying to validate is image, then the first parameter of file_save_upload should be image, as such:

$path = file_save_upload('image', ...);

This function will then return the path on the server to which the image was uploaded (so you can for example store that path in a custom database field).


You are missing this in your form definition:

   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit

Here's the logic I use to create a file upload widget on a form:

   // these give us the file upload widget: 
   $form['#attributes']['enctype'] = 'multipart/form-data'; // If this is not here, upload will fail on submit
   $form['fid'] = array( '#title'        => t('Upload image'),
                         '#type'         => 'file',
                         '#description'  => t('Images must be one of jpg, bmp, gif or png formats.'),

And here's the counterpart to that logic, which I have in my form's validate callback, because I have image filename restrictions in my logic, but you can place this in the submit callback if you want:

   // @see: http://api.drupal.org/api/function/file_save_upload/6
   // $file will become 0 if the upload doesn't exist, or an object describing the uploaded file
   $file = file_save_upload( 'fid' );
   error_log( 'file is "'.print_r( $file, true ).'"' );
   if (!$file) {
      form_set_error('fid', t('Unable to access file or file is missing.'));

that's it.

  • 3
    You actually don't need $form['#attributes']['enctype'] in Drupal 7. It's taken care of automatically
    – user724228
    Commented Sep 15, 2011 at 23:41
  • 3
    you don't need the multipart/form-data for drupal 7, It is build in drupal 7 when using a file field.
    – FLY
    Commented Sep 4, 2012 at 13:34
  • @bsenftner I'm using the same method as you are, but when I try it out, I find that $file === null, which means that no file was uploaded (according to the specs: api.drupal.org/api/drupal/includes!file.inc/function/…) What should I do in that case? How can I debug this kind of thing?
    – Shawn
    Commented Oct 10, 2012 at 19:26
  • @Shawn: are you working in Drupal 7? This logic is tested for Drupal 6. I've not had a chance to try it on D7 yet, so, if you're in D7 then "I don't know". If you're in D6, then it should be working - are you sure 'fid' is the field name of your file upload widget? Commented Oct 10, 2012 at 23:21
  • Yes to both questions: I'm sure I've got the right name for the widget and I'm using D7. I think I should make this a new question...
    – Shawn
    Commented Oct 11, 2012 at 13:33

I have a generic validation function I use primarily in themes that need to support upload of images. You might be able to use it as it, or with minor changes, but this should get you far.

 * Validate/submit handler used for handling image uploads
function module_upload_image_validate($form, &$form_state) {
  // This is not needed, I use this to use the same validate function
  // for several fields.
  $key = $form['#key'];
  $file = file_save_upload($key, array(
    'file_validate_is_image' => array(),
    'file_validate_extensions' => array('png gif jpg jpeg'),
  if ($file) {
    // Get the image info to get the correct extension for the uploaded file.
    $info = image_get_info($file->filepath);
    if (file_move($file, 'destination/filename'. $info['extension'], FILE_EXISTS_REPLACE)) {
      // Mark the file for permanent storage.
      file_set_status($file, FILE_STATUS_PERMANENT);
      // Update the files table.
      drupal_write_record('files', $file, 'fid');
      $form_state['values'][$key] = $file->filepath;
    else {
      form_set_error($key, t('Failed to write the uploaded file to the site’s files folder.'));

Using this function, you will get the filepath as the the value in form submit handler. You might want the file id instead, depending on your usage.

Not the answer you're looking for? Browse other questions tagged or ask your own question.