Jump to content

Extract file extension from an uploaded file


jo.nova

Recommended Posts

I'm trying to isolate the file extension of  uploaded files so that I can check them for validity.  For example, say I want to only accept ".zip" files:

Let's say the value of $_FILES['somefile']['name'] is "afile.zip"; I want to put just the extension in a variable and check it against a predefined set of strings.  I can setup the string filtering, but I don't know how to tell PHP to look at just the last three characters in a file name.

Any help?
Link to comment
Share on other sites

another easy way of doing this is to use strrchr:

[code]<?php
$filename = 'something.zip';
$extension = strrchr($filename, '.');
?>[/code]

would yield '.zip' in $extension.  use substr() if you want to remove the period as well.
Link to comment
Share on other sites

$allowed = array('image/gif', 'image/jpeg', 'image/png');
if (in_array($_FILES['upload']['type'], $allowed) {
  // Continue to process
}
else {
  // Tell them its bad
}

And replace ['upload'] with whatever the name of the input you use is.
Link to comment
Share on other sites

WOW! Thanks, guys.  I go to lunch, and return to find an entire disseratation on my topic.  Much appreciated!  I'm lovin' PHP; way better than my boring-ass C++ class. Thanks!

Now, here's the next part I just realized:

How do I make the match case insenstive?  (Just in case someone happens to have their file extension in caps)
Link to comment
Share on other sites

[quote author=jo.nova link=topic=100459.msg396480#msg396480 date=1152808755]
I'm trying to isolate the file extension of  uploaded files so that I can check them for validity.  For example, say I want to only accept ".zip" files:

Let's say the value of $_FILES['somefile']['name'] is "afile.zip"; I want to put just the extension in a variable and check it against a predefined set of strings.  I can setup the string filtering, but I don't know how to tell PHP to look at just the last three characters in a file name.

Any help?
[/quote]

the thing is, an extension can be more than 3 characters so you wouldn't be doing a thorough job if you looked at the last 3 characters.
also, a file can be a text file and have a ".zip" extension or it could be a malicious exe and have a ".jpg" extension.
and if you plan to upload files such as tar.gz or tar.bz, etc (files with more than one extension - in this example, the file is an archived and compressed file), you would have to have some sort of work around to detect such extensions.


there are two options:
1. maintain an array of files with more than one extension that you permit. and first check if the last two blocks of characters (by a period) are in the array (using in_array()) that you maintain. if not, take the block of characters after the last period and check against that. i used to use this:
[code=php:0]
echo end(explode('.', $fileName));
[/code]
but i think akitchin's strrchr() is faster than an explode.

2. match the value of $_FILES['upload']['type'] or mime_content_type() against an array of allowed MIME's and allow or disallow accordingly.



you might find this useful: [url=http://www.ace.net.nz/tech/TechFileFormat.html]Almost Every file format in the world![/url]
or you could refer to /etc/mime.types if you're on a linux machine.
Link to comment
Share on other sites

So would this work?:

[code=php:0]//put filename in a variable before checking file extension
$filetypecheck = ($_FILES['FileName']['name']);

//put file's extension in a variable
$extension = strrchr($filetypecheck, '.');

// check to see if a file was entered and if that file is a valid type
if ((!$_FILES['FileName']['name']) || ($extension !== "zip" || "sit" || "jpg" || "pdf" || "tif" || "gif" || "eps" || "psd"))

// if not, add that error to our array
$errors[] = '- Your file to be printed (in one of the acceptable formats)';[/code]


Or does it have to be like this?:

[code=php:0]//put filename in a variable before checking file extension
$filetypecheck = ($_FILES['FileName']['name']);

//put file's extension in a variable
$extension = strrchr($filetypecheck, '.');

// check to see if a file was entered and if that file is a valid type
if ((!$_FILES['FileName']['name']) || ($extension !== "zip") || ($extension !== "sit") || ($extension !== "jpg") || ($extension !== "pdf") || ($extension !== "tif") || ($extension !== "gif") || ($extension !== "eps") || ($extension !== "psd"))

// if not, add that error to our array
$errors[] = '- Your file to be printed (in one of the acceptable formats)';[/code]


I'm new, so bear with me!
Link to comment
Share on other sites

it would be the latter format for the if() statement (ie. one condition for every possible extension), but three things:

1.  i would suggest simply putting all of your allowed extensions into an array and checking if the extension is in that array or not using in_array() (check the manual on the syntax).
2.  your logic is flawed.  it will check if the filename isn't set OR the extension isn't zip OR the extension isn't sit, etc.  it can't be both sit and zip at the same time, so it will always fail.  you'll need to change the extension checks to && (and operator).  using an array greatly simplifies this statement.
3.  strrchr() returns the '.' in the extension as well.  either change your allowed extensions to include the period or use substr() to remove the period in the file's extension (see manual for syntax).
Link to comment
Share on other sites

:Edit: akitchin has replied by the time i modified the code and posted it...but i'll post it anyway :)


first you would have to tell me if you intend to upload files that can have two valid extensions like tar.gz, etc.

if not, you would modify your code to this:

[code=php:0]
//put filename in a variable before checking file extension
$filetypecheck = trim($_FILES['FileName']['name']);

//put file's extension in a variable
$extension = strrchr($filetypecheck, '.');


$validTypes = array('.zip', '.sit', '.jpg', '.pdf', '.tif', '.gif', '.epf', '.psd');



// check to see if a file was entered and if that file is a valid type
if(!empty($filetypecheck) && in_array($extension, $validTypes))
{
echo 'valid upload format';
}
else
{
echo 'invalid upload format';
}
[/code]



there's a bunch of other things you should look into if you want to strictly allow only files of a certain type but it seems like you're not very particular about that so this should work ok as far as i know.

hope that helped :)
Link to comment
Share on other sites

akitchin, thanks everything you said worked out great!

Koobi, thanks man, got it working in the meantime.  Here's how I implemented it:

[code=php:0]
//put filename in a variable before checking file extension
$filetypecheck = ($_FILES['FileName']['name']);
//put file's extension in a variable
$extension = strrchr($filetypecheck, '.');

//make an array of allowed extensions
$allowext = array(".zip",".sit",".tif",".jpg",".pdf",".eps",".gif",".psd");

// check to see if a file was entered and if that file is a valid type
if ((!$_FILES['FileName']['name']) || (!in_array($extension, $allowext)))
// if not, add that error to our array
$errors[] = '- Your file to be printed (in one of the acceptable formats)';
[/code]


We're a printshop, so we're probably not gonna get anything like .gz files from customers since almost the entire industry is using Macs.

Thanks guys!  I hope to get as proficient at this so that I can help others someday as well!
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.