Author image
Senior Developer

File uploads in Drupal 6 - Part 1

So you've got a nice new version of Drupal 6 and you're building a form, but you want to allow users to upload a file. Of course this is easy with Drupal, and we covered how to do just that, but for Drupal 5, in our previous article: Example code to build an upload form in Drupal. Here we show how file uploads are done in Drupal 6.

Honestly, not much has changed, here's the code to get your file upload element onto your form:

function build_upload_form(){
    $form['#attributes'] = array('enctype' => 'multipart/form-data');
    $form['file_upload'] = array(
        '#type' => 'file',
        '#title' => 'Filename'
    $form['submit'] = array(
        '#type' => 'submit',
        '#value' => 'Upload file'
    return $form;

Nothing has changed since Drupal 5 there, but the changes come in the submit function:

function upload_form_submit($form, &$form_state) {

  //define your limits for the submission here
  $limits = array ( ... ) ;

  $validators = array(
    'file_validate_extensions' => array($limits['extensions']),
    'file_validate_image_resolution' => array($limits['resolution']),
    'file_validate_size' => array(

  // Save new file uploads.
  if ($file = file_save_upload('file_upload', $validators, file_directory_path())) {
    // Do something with $file here.

We have a big change here, we can define an array of file validation functions to pass to file_save_upload and only if the file conforms to those will it be saved.

File validation functions:

These are simply functions that receive the $file object as their first parameter and extra parameters as defined in your invocation of file_save_upload(). Drupal core comes with four:

  1. file_validate_extensions() checks that the file extension in the given list
  2. file_validate_size() checks for maximum file sizes and against a user's quota
  3. file_validate_is_image() checks that the upload is an image
  4. file_validate_image_resolution() checks that images meets maximum and minimum resolutions requirements.

You can always write your own to check extra things, you just need to return an array of error messages if there are any, and an empty array if not. More information can be found in the Drupal handbook.

Next Steps

We're not going to cover what you could do with your uploaded and validated file object, but there is one obvious thing that you might want to do before all that: AJAX uploading.
Drupal's core upload module allows you to upload files to nodes, and provides a nice 'attach' button which starts the upload process in the background leaving users free to fill in the rest of the form, doing this with your own forms turns out to be quite challenging, as we shall see in the next part of this tutorial!


Nice post, looking forward to the AJAX version :)

Yes, very interesting article, thanks!

Thanks for a really useful tutorial - so where's part 2? or did you decide to cheat and just integrate SWFUpload or something similar with your drupal?

Thanks, really looking forward to the AJAX version, any idea when you're goin to publish that one?

I have same problem with Arek, the upload doesn't work and there's no error statement.. Help please.. Thx..

thanks such a grate post

thanks a lot

thanks such a grate post

thanks a lot

One thing I've noticed in D6 with file uploads is that using only file_save_upload() will result in your file being purged on a subsequent drupal cron run. This happens because all files are uploaded in Drupal with a status of 0.

Therefore, you should be calling your hook_submit more like this...

// Save new file uploads.
if ($file = file_save_upload('file_upload', $validators, file_directory_path())) {

// Do something with $file here.

//Make file permanent
file_set_status($file, FILE_STATUS_PERMANENT);

Hopefully this helps someone. I spent a bit of time on this before I really understood why my files were disappearing.

should this

// Save new file uploads.
if ($file = file_save_upload('upload', $validators, file_directory_path())) {
// Do something with $file here.


// Save new file uploads.
if ($file = file_save_upload('file_upload', $validators, file_directory_path())) {
// Do something with $file here.

Isn't hook_submit deprecated (or even left out) of drupal 6?


thanks for this nice artcile. it would be great if you could explain about how to use file_validate_extensions or simillar file functions as stand alone unlike you used it in file_save_upload() function.

Thanks in advance

please note that there's a small bug in the posted sample code above, as pointed out by errata

in the build_upload_form() function, the name of the upload field is "file_upload", but in the upload_form_submit() function you refer to the uploaded file as though the file upload field was named "upload"

file_save_upload('upload', $validators, file_directory_path())

that won't work - needs to be

file_save_upload('file_upload', $validators, file_directory_path())

Thank you errata, xurizaemon! I have edited the post. Cheers, G

Hi i have read some comments regards ajax version.

But as i knw file upload is not support by ajax. right ?????


You can use AHAH to do file uploads, as core does it. I'll get around to writing part 2 of this tutorial at some point, and you'll see how!

If you could put valued in the $limits array it would have been great. There is some confusions on how it works. :)


it works great

what about uploading multiple files?

it is not working for me. when I push upload button it looks like file is being uploaded but it is not saved anywhere. there is not of any errors so I don't know what is wrong :(

Comments on this article are now closed, if you want to give us feeback you can use our contact form instead.