tags:

views:

1628

answers:

5

I'm working on a PHP upload script which allows .mp3 file uploads amongst others. I've created an array which specifies permitted filetypes, including mp3s, and set a maximum upload limit of 500MB:

// define a constant for the maximum upload size
define ('MAX_FILE_SIZE', 5120000);

// create an array of permitted MIME types
$permitted = array('application/msword', 'application/pdf', 'text/plain', 'text/rtf', 'image/gif', 'image/jpeg', 'image/pjpeg', 'image/png', 'image/tiff', 'application/zip', 'audio/mpeg', 'audio/mpeg3', 'audio/x-mpeg-3', 'video/mpeg', 'video/mp4', 'video/quicktime', 'video/x-ms-wmv', 'application/x-rar-compressed');

So far in testing all specified filetypes have been successfully uploaded but for some reason it comes up with an error for .mp3. As you can see above I've included audio/mpeg, audio/mpeg3, and audio/x-mpeg-3 but none of them seem to make a difference.

Can someone suggest what the problem could be and also indicate which audio type is the one needed to allow .mp3 uploads?

Thanks

Update: The code I'm using to run the check on the file is as follows:

// check that file is within the permitted size
     if ($_FILES['file-upload']['size'][$number] > 0 || $_FILES['file-upload']['size'][$number] <= MAX_FILE_SIZE) {
      $sizeOK = true;
     }

     // check that file is of an permitted MIME type
     foreach ($permitted as $type) {
        if ($type == $_FILES['file-upload']['type'][$number]) {
          $typeOK = true;
          break;
         }
       }

     if ($sizeOK && $typeOK) {
        switch($_FILES['file-upload']['error'][$number]) {
          case 0:
             // check if a file of the same name has been uploaded
          if (!file_exists(UPLOAD_DIR.$file)) {
            // move the file to the upload folder and rename it
            $success = move_uploaded_file($_FILES['file-upload']['tmp_name'][$number], UPLOAD_DIR.$file);
           }
          else {
            // strip the extension off the upload filename
            $filetypes = array('/\.doc$/', '/\.pdf$/', '/\.txt$/', '/\.rtf$/', '/\.gif$/', '/\.jpg$/', '/\.jpeg$/', '/\.png$/', '/\.tiff$/', '/\.mpeg$/', '/\.mpg$/', '/\.mp4$/', '/\.mov$/', '/\.wmv$/', '/\.zip$/', '/\.rar$/', '/\.mp3$/');
            $name = preg_replace($filetypes, '', $file);
            // get the position of the final period in the filename
            $period = strrpos($file, '.');
            // use substr() to get the filename extension
            // it starts one character after the period
            $filenameExtension = substr($file, $period+1);
            // get the next filename 
            $newName = getNextFilename(UPLOAD_DIR, $name, $filenameExtension); 
            $success = move_uploaded_file($_FILES['file-upload']['tmp_name'][$number], UPLOAD_DIR.$newName);
        }
          if ($success) {
               $result[] = "$file uploaded successfully";
              }
          else {
            $result[] = "Error uploading $file. Please try again.";
           }
             break;
          case 3:
          $result[] = "Error uploading $file. Please try again.";
       default:
             $result[] = "System error uploading $file. Contact webmaster.";
         }
       }
     elseif ($_FILES['file-upload']['error'][$number] == 4) {
        $result[] = 'No file selected';
       }
     else {
        $result[] = "$file cannot be uploaded. Maximum size: $max. Acceptable file types: doc, pdf, txt, rtf, gif, jpg, png, tiff, mpeg, mpg, mp3, mp4, mov, wmv, zip, rar.";
       }

I'm getting the bottom else result telling me either the file size is wrong or the extension isn't allowed.

Update 2: I've run a print_r of the _FILES array to hopefully provide a little more info. The results are:

Array ( [file-upload] => Array ( [name] => Array ( [0] => Mozart.mp3 [1] => [2] => )

        [type] => Array
            (
                [0] => audio/mpg
                [1] => 
                [2] => 
            )

        [tmp_name] => Array
            (
                [0] => /Applications/MAMP/tmp/php/phpgBtlBy
                [1] => 
                [2] => 
            )

        [error] => Array
            (
                [0] => 0
                [1] => 4
                [2] => 4
            )

        [size] => Array
            (
                [0] => 75050
                [1] => 0
                [2] => 0
            )

    )

)

A: 

The 5MB limit is probably your problem.

Andy
+7  A: 

MAX_FILE_SIZE is a value in Bytes

5120000 is not 500 MB. It's 5MB by my reckoning.

You'll also need to check that you're not exceeding the "post_max_size" and "upload_max_size" variables in your php.ini file

Secondly, an mp3 can be any of the following mimetypes

  • audio/mpeg
  • audio/x-mpeg
  • audio/mp3
  • audio/x-mp3
  • audio/mpeg3
  • audio/x-mpeg3
  • audio/mpg
  • audio/x-mpg
  • audio/x-mpegaudio

http://filext.com/file-extension/MP3

Eoin Campbell
Good point. I've now added an extra zero which should make it about 48MB:// define a constant for the maximum upload sizedefine ('MAX_FILE_SIZE', 51200000);Also, I've changed "post_max_size" and "upload_max_size" to be 64MB. I've confirmed this with phpinfo().The music file is 5.8MB but after changing the max size to 48MB I still get the error that it wasn't uploaded. This is just the error I set myself in the if/else conditional.
I've also now added all the mp3 filetypes you listed above so the array now reads:$permitted = array('application/msword', 'application/pdf', 'text/plain', 'text/rtf', 'image/gif', 'image/jpeg', 'image/pjpeg', 'image/png', 'image/tiff', 'application/zip', 'audio/mpeg', 'audio/mpeg3', 'audio/mp3', 'audio/x-mpeg', 'audio/x-mp3', 'audio/x-mpeg3', 'audio/x-mpg', 'audio/x-mpegaudio', 'audio/x-mpeg-3', 'video/mpeg', 'video/mp4', 'video/quicktime', 'video/x-ms-wmv', 'application/x-rar-compressed');
if that hasn't worked, then you're going to need to post more info.Edit your question to include the code where you actually do the upload (the if/else you referred to). Also get some code to dump the mime/type of the file that's being uploaded.
Eoin Campbell
Can you specify what code to include and where's best to include it to print the mime/type of the file being uploaded?
A: 
Nick Presta
Thanks for the code, I'm not exactly sure where or how to include it - sorry I'm using this as a learning project. However, I have printed the results of the $_FILES array of the upload and updated my post above. It seems it does produce error = 4 but I too am not sure what's causing it.Does this provide any useful info or shall I try and include your code? If so, any more specific instructions?
A: 

You should never assume the value in $_FILES[...]['type'] actually matches the type of the file. The client can send any arbitrary string, and it's not checked at all by PHP. See here.

You'll have to do the work yourself to actually determine what type of file was uploaded, unless you have a good reason not to care about security at all (which you probably don't). PHP provides the fileinfo package by default, which does the heavy lifting for you. See finfo_file().

chazomaticus
Thanks for the security tips. I've been building it from the ground up with security a big concern so I'll read the links and try and include checking for this. All part of the learning process but thanks for pointing it out.First things first though, whilst I'm just working locally and I'm the only use I'm still trying to get the functionality working so any tips on how to sort out the .mp3 upload problem would also be greatly appreciated. Anyone have any ideas?
A: 
  1. why not use in_array rather than the foreach loop for type check?
  2. when you upload a valid file, have you tried checking the values of the $sizeOK & $typeOK
Moutaz