1

I created a custom form with a file upload field:

$form['csvfile'] = array(
    '#title' => 'CSV File',
    '#type' => 'file',
);

When I submit the form, I can see the correct information in the $_FILES array:

enter image description here

However, when I try to use the code in the examples module to get the contents of that file and write it to an unmanaged file, the file is empty.

enter image description here

So, the resulting file is 0 bytes long.

How do I access the uploaded file in a drupal-y way? I know I can just use the basic PHP functions to access the file, but I'm trying to learn how to do it the way drupal intends.

My submit handler code is almost entirely lifted from the examples module.

function herdapi_form_bulkupload($form, &$form_state) {
    $form = array();
    $form['email'] = array(
        '#title' => 'Owner Email',
        '#type' => 'textfield',
    );

    $form['password'] = array(
        '#title' => 'Password',
        '#type' => 'password',
    );

    $form['csvfile'] = array(
        '#title' => 'CSV File',
        '#type' => 'file',
    );

    $form['submit'] = array(
        '#value' => 'Upload',
        '#type' => 'submit',
    );

    $form_state['rebuild'] = TRUE;
    $form_state['redirect'] = FALSE;

    return $form;
}

function mymodule_form_bulkupload_submit($form, &$form_state) {

    dsm($form_state);
    dsm($_FILES);
    $data = $form_state['values']['csvfile'];

    // With the unmanaged file we just get a filename back.
    $filename = file_unmanaged_save_data($data, NULL, FILE_EXISTS_REPLACE);
    if ($filename) {
        $url = file_create_url($filename);
        $_SESSION['file_example_default_file'] = $filename;
        drupal_set_message(
            t('Saved file as %filename (accessible via !url, uri=<span id="uri">@uri</span>)',
                array(
                    '%filename' => $filename,
                    '@uri' => $filename,
                    '!url' => l(t('this URL'), $url),
                )
            )
        );
    }
    else {
        drupal_set_message(t('Failed to save the file'), 'error');
    }
}
1

Drupal forms which include a file upload field must also set the encoding type to multipart/form-data.

  $form['#attributes']['enctype'] = 'multipart/form-data';

Reference: Drupal.org: Uploading Files


There is a good checklist for debugging your situation here:

https://stackoverflow.com/questions/3586919/why-would-files-be-empty-when-uploading-files-to-php

Not mentioned in the checklist there is that Suhosin, a commonly installed extension, can empty some submitted values. As well as following the checklist in the linked question, check to see if you have Suhosin installed - if so then you may be

One thing I'd try straight away is whether uploading a very small file triggers this bug. If so that might suggest that you're hitting a limit in PHP's max post data or Suhosin.

  • I see your file above is 3613B, which qualifies as "very small". Suhosin is unlikely to get triggered by this unless it's massively misconfigured, or the .csv looks somehow malicious to it ... – Chris Burgess Mar 9 '14 at 6:20
  • Thanks! I went through the checklist. 1) My php.ini is properly configured. 2) I'm not adding any javascript, it's all just standard drupal forms. 3) No duplicate fields. 4) I'm on linux, so my /tmp dir is properly permissioned. 5) no spaces in the filenames 6) form tags are closed 7) form has enctype 8) method is post 9) has name attribute 10) no special chars, I tried text.txt with a single ascii char in it. 11) using standard drupal .htaccess 12) not using any underscores in the name. 13) I don't have Suhosin installed. checked phpinfo() and it's not there. :( – Kenny Wyland Mar 9 '14 at 6:58
  • Suggest posting enough of the module (form, validate and submit handlers at a minimum) that you could break it out into a separate module (=> then site) to test it. Phrasing your question this way frequently isolates the issue you're having, and makes it much easier for other people to support you. Once you've done this you can easily try it out on a bare Drupal install ("drush qd") and that will tell you if the issue relates to other modules enabled & make it easier to check a different server environment. – Chris Burgess Mar 9 '14 at 7:07
  • I've updated the post to include my form method. I don't have a validate method, and I've already provided the submit method. Thanks for your help. – Kenny Wyland Mar 11 '14 at 1:20
  • Answer updated. Please try that? This is item 7 in the checklist linked earlier. – Chris Burgess Mar 11 '14 at 10:05
0

Even though this is an old question, it is among the first results when looking for this matter using Google. The answer is found in https://www.drupal.org/node/1537950 from where I modify a little the original code:

function mymodule_form_bulkupload_validate($form, &$form_state) {
  $file = file_save_upload('csvfile', array(
    'file_validate_extensions' => array('csv'),
  ));
  if (!$file) {
    form_set_error('csvfile', 'No file was uploaded');
  }
  $form_state['values']['file'] = $file;
}

Long story short, since this isn't a managed_file, Drupal doesn't do anything more than just add the "multipart/form-data" to the enctype attribute of the form. Anything more, like saving locally the $_FILES, validating and adding the $file to the $form_state array is something you are responsible for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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