waynew Posted September 3, 2009 Share Posted September 3, 2009 Not so long ago I did a CMS for a large website. When the client creates/edits a page, he or she can upload file attachments with it. These are usually PDF files or .doc files. Their hosting is on a Windows server. Whenever they try to upload certain PDF Files, my code tells them that it's not a valid filetype. So, I got them to send me the PDFs via email. I checked their mimetype and sure enough they were application/pdf. I then attempted to upload them with my local copy of the CMS and it worked. They were only a few hundred KB in size, so I'm guessing that size wasn't the problem. In the CMS DB, there is a table that contains the rows of accepted filetypes. When they upload a file, my code checks that table to see if the mime type of the file matches up with a mime type in the table. The function that checks this is in my file class: protected function get_extension($filetype){ $filetype = $this->db->clean($filetype); $res = $this->db->get_row("SELECT filetype_id, extension FROM filetype WHERE mime_type = '$filetype'"); if(!$res){ return false; } else{ return $res; } } $db->get_row() returns false if it couldn't find a single unique row. If that single unique rows exists, it returns an array. Oh, and yes, they have successfully uploaded PDFs using that code before. Quote Link to comment Share on other sites More sharing options...
waynew Posted September 3, 2009 Author Share Posted September 3, 2009 Oh and no comment about the last few lines of redundant code. Quote Link to comment Share on other sites More sharing options...
trq Posted September 3, 2009 Share Posted September 3, 2009 Where is the code the defines the $filetype variable passed to this method? Quote Link to comment Share on other sites More sharing options...
waynew Posted September 3, 2009 Author Share Posted September 3, 2009 $extension = $this->get_extension($_FILES[$fieldname]['type']); $fieldname is the name of the filefield form item being uploaded. Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted September 3, 2009 Share Posted September 3, 2009 Is your code checking for upload errors $_FILES[$fieldname]['error'] prior to that point so that you know that $filetype even has anything in it? Real applications should log (see error_log) information about things that fail (and even for some things what work, like who logged in when or what search terms are being used...) so that you have a record of problems and can find and fix them. At the point that the query returns an unexpected value you should log all the available who, what (what does $filetype actually contain), when, where, and why (is $res a FALSE value, meaning the query failed to execute at all or is it a result resource with zero rows in it, meaning the query executed but matched zero rows) information and you should also display the $_FILES[$fieldname]['type'] value that failed in the user error message. Quote Link to comment Share on other sites More sharing options...
waynew Posted September 3, 2009 Author Share Posted September 3, 2009 Hi, I have this in my code too: if($_FILES[$fieldname]['error'] != 0){ $error = $_FILES[$fieldname]['error']; if($error == 1){ $this->error->add("Server problem: The uploaded file exceeds the upload_max_filesize directive set by the hosting company."); return false; } if($error == 2){ $this->error->add("The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form."); return false; } if($error == 3){ $this->error->add("Server/Connection problem: The uploaded file was only partially uploaded."); return false; } if($error == 6){ $this->error->add("Server problem: No temporary upload folder was found."); return false; } if($error == 7){ $this->error->add("Server problem: Could not write to disk."); return false; } } I tried it; but still end up getting a message about how the file isn't the right type: if(!$extension){ $this->error->add("The filetype under the title <strong>".$this->db->output($title)."</strong> has not been recognised and has therefore not been added to the page that you just created."); return false; } Quote Link to comment Share on other sites More sharing options...
waynew Posted September 3, 2009 Author Share Posted September 3, 2009 Sorry for the way it's showing up there. Code looks fine on Dreamweaver. Quote Link to comment Share on other sites More sharing options...
xylex Posted September 3, 2009 Share Posted September 3, 2009 $_FILES[$fieldname]['type'] is a client set variable, not a server one. This may have different capitalization or have other slight variations depending on the client computer, which would explain the behavior you're seeing. Why not just filter by extension? Quote Link to comment Share on other sites More sharing options...
Daniel0 Posted September 3, 2009 Share Posted September 3, 2009 You can also check the MIME type on server side: http://php.net/fileinfo Quote Link to comment Share on other sites More sharing options...
PFMaBiSmAd Posted September 3, 2009 Share Posted September 3, 2009 Different browsers, the same browser on different operating systems, and probably different versions of the same browser will provide different mime types for the same identical file. Nothing I have seen so far in this thread indicates what actual value is being received when the customer tries this. For all we know the customer is not actually selecting a file, but is just submitting an empty form or that the HTML of the form is invalid and it uploads a file in one browser but not another. Until you display and/or log what value is actually being put into the query that is failing to indicate a match with something in the database, you will never find out why it is failing. Quote Link to comment Share on other sites More sharing options...
waynew Posted September 8, 2009 Author Share Posted September 8, 2009 Figured out the problem. Basically, my $db->get_row() function returns an array if one row is found. It returns false if no rows are found OR if more than one row was found. I or somebody else must have ran the setup file twice by accident, meaning that two of every mime type existed inside the db. Should have really put a unique index on the mime_type column but I remember that at the time, I chose not too because my setup file would be inserting these file types manually and performance wouldn't be such an issue with a table so small. I tried using fileinfo(), but their server doesn't have support for it installed. So I got the file's extension instead and worked from there. It was only after I had changed the script to get the extension of the file that I figured out what was wrong. Interesting thing about $_FILES['name']['type'] though. I honestly never knew that. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.