This is a question you can read everywhere on the web with various answers:
$ext = end(explode('.', $filename));
$ext = substr(strrchr($filename, '.'), 1);
$ext = substr($filename, strrpos($filename, '.') + 1);
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $filename);
$exts = split("[/\\.]", $filename);
$n = count($exts)-1;
$ext = $exts[$n];
etc.
However, there is always "the best way" and it should be on Stack Overflow.
People from other scripting languages always think theirs is better because they have a built-in function to do that and not PHP (I am looking at Pythonistas right now :-)).
In fact, it does exist, but few people know it. Meet pathinfo():
$ext = pathinfo($filename, PATHINFO_EXTENSION);
This is fast and built-in. pathinfo() can give you other information, such as canonical path, depending on the constant you pass to it.
Remember that if you want to be able to deal with non ASCII characters, you need to set the locale first. E.G:
setlocale(LC_ALL,'en_US.UTF-8');
Also, note this doesn't take into consideration the file content or mime-type, you only get the extension. But it's what you asked for.
Lastly, note that this works only for a file path, not a URL resources path, which is covered using PARSE_URL.
Enjoy
pathinfo()
$path_info = pathinfo('/foo/bar/baz.bill');
echo $path_info['extension']; // "bill"
Example URL: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ
A) Don't use suggested unsafe PATHINFO:
pathinfo($url)['dirname'] 🡺 'http://example.com/myfolder'
pathinfo($url)['basename'] 🡺 'sympony.mp3?a=1&b=2#XYZ' // <------- BAD !!
pathinfo($url)['extension'] 🡺 'mp3?a=1&b=2#XYZ' // <------- BAD !!
pathinfo($url)['filename'] 🡺 'sympony'
B) Use PARSE_URL:
parse_url($url)['scheme'] 🡺 'http'
parse_url($url)['host'] 🡺 'example.com'
parse_url($url)['path'] 🡺 '/myfolder/sympony.mp3'
parse_url($url)['query'] 🡺 'aa=1&bb=2'
parse_url($url)['fragment'] 🡺 'XYZ'
BONUS: View all native PHP examples
There is also SplFileInfo:
$file = new SplFileInfo($path);
$ext = $file->getExtension();
Often you can write better code if you pass such an object around instead of a string. Your code is more speaking then. Since PHP 5.4 this is a one-liner:
$ext = (new SplFileInfo($path))->getExtension();
Do it faster!
In other words, if you only work with a filename, please stop using pathinfo.
I mean, sure if you have a full pathname, pathinfo makes sense because it's smarter than just finding dots: the path can contain dots and filename itself may have none. So in this case, considering an input string like d:/some.thing/myfile, pathinfo and other fully equipped methods are a good choice.
But if all you have is a filename, with no path, it's simply pointless to make the system work a lot more than it needs to. And this can give you a 10x speed boost.
Here's a quick speed test:
/* 387 ns */ function method1($s) {return preg_replace("/.*\./","",$s);} // edge case problem
/* 769 ns */ function method2($s) {preg_match("/\.([^\.]+)$/",$s,$a);return $a[1];}
/* 67 ns */ function method3($s) {$n = strrpos($s,"."); if($n===false) return "";return substr($s,$n+1);}
/* 175 ns */ function method4($s) {$a = explode(".",$s);$n = count($a); if($n==1) return "";return $a[$n-1];}
/* 731 ns */ function method5($s) {return pathinfo($s, PATHINFO_EXTENSION);}
/* 732 ns */ function method6($s) {return (new SplFileInfo($s))->getExtension();}
// All measured on Linux; it will be vastly different on Windows
Those nanosecond values will obviously differ on each system, but they give a clear picture about proportions. SplFileInfo and pathinfo are great fellas, but for this kind of job it's simply not worth it to wake them up. For the same reason, explode() is considerably faster than regex. Very simple tools tend to beat more sophisticated ones.
Conclusion
This seems to be the Way of the Samurai:
function fileExtension($name) {
$n = strrpos($name, '.');
return ($n === false) ? '' : substr($name, $n+1);
}
Remember this is for simple filenames only. If you have paths involved, stick to pathinfo or deal with the dirname separately.
As long as it does not contain a path you can also use:
array_pop(explode('.', $fname))
Where $fname is a name of the file, for example: my_picture.jpg.
And the outcome would be: jpg
E-satis's response is the correct way to determine the file extension.
Alternatively, instead of relying on a files extension, you could use the fileinfo to determine the files MIME type.
Here's a simplified example of processing an image uploaded by a user:
// Code assumes necessary extensions are installed and a successful file upload has already occurred
// Create a FileInfo object
$finfo = new FileInfo(null, '/path/to/magic/file');
// Determine the MIME type of the uploaded file
switch ($finfo->file($_FILES['image']['tmp_name'], FILEINFO_MIME)) {
case 'image/jpg':
$im = imagecreatefromjpeg($_FILES['image']['tmp_name']);
break;
case 'image/png':
$im = imagecreatefrompng($_FILES['image']['tmp_name']);
break;
case 'image/gif':
$im = imagecreatefromgif($_FILES['image']['tmp_name']);
break;
}
1) If you are using (PHP 5 >= 5.3.6)
you can use SplFileInfo::getExtension — Gets the file extension
Example code
<?php
$info = new SplFileInfo('test.png');
var_dump($info->getExtension());
$info = new SplFileInfo('test.tar.gz');
var_dump($info->getExtension());
?>
This will output
string(3) "png"
string(2) "gz"
2) Another way of getting the extension if you are using (PHP 4 >= 4.0.3, PHP 5) is pathinfo
Example code
<?php
$ext = pathinfo('test.png', PATHINFO_EXTENSION);
var_dump($ext);
$ext = pathinfo('test.tar.gz', PATHINFO_EXTENSION);
var_dump($ext);
?>
This will output
string(3) "png"
string(2) "gz"
// EDIT: removed a bracket
Sometimes it's useful to not to use pathinfo($path, PATHINFO_EXTENSION). For example:
$path = '/path/to/file.tar.gz';
echo ltrim(strstr($path, '.'), '.'); // tar.gz
echo pathinfo($path, PATHINFO_EXTENSION); // gz
Also note that pathinfo fails to handle some non-ASCII characters (usually it just suppresses them from the output). In extensions that usually isn't a problem, but it doesn't hurt to be aware of that caveat.
Sorry... "Short Question; But NOT Short Answer"
Example 1 for PATH
$path = "/home/ali/public_html/wp-content/themes/chicken/css/base.min.css";
$name = pathinfo($path, PATHINFO_FILENAME);
$ext = pathinfo($path, PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);
Example 2 for URL
$url = "//www.example.com/dir/file.bak.php?Something+is+wrong=hello";
$url = parse_url($url);
$name = pathinfo($url['path'], PATHINFO_FILENAME);
$ext = pathinfo($url['path'], PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);
Output of example 1:
Name: base.min
Extension: css
Output of example 2:
Name: file.bak
Extension: php
References
https://www.php.net/manual/en/function.pathinfo.php
https://www.php.net/manual/en/function.realpath.php
https://www.php.net/manual/en/function.parse-url.php
The simplest way to get file extension in PHP is to use PHP's built-in function pathinfo.
$file_ext = pathinfo('your_file_name_here', PATHINFO_EXTENSION);
echo ($file_ext); // The output should be the extension of the file e.g., png, gif, or html
You can try also this (it works on PHP 5.* and 7):
$info = new SplFileInfo('test.zip');
echo $info->getExtension(); // ----- Output -----> zip
Tip: it returns an empty string if the file doesn't have an extension
The "best" way depends on the context and what you are doing with that file extension.
However,
🥇 pathinfo in general is the best when you consider all the angles.
pathinfo($file, PATHINFO_EXTENSION)
It is not the fastest, but it is fast enough. It is easy to read, easy to remember and reuse everywhere. Anyone can understand it at a glance and remove PATHINFO_EXT flag if they need more info about the file.
❌ strrpos method. described in several answers is faster yes but requires additional safety checks which, in turn, requires you to wrap it inside a function, to make it easily reusable.
Then you must take the function with you from project to project or look it up.
Wrapping it in a function call with extra checks also makes it slower and if you need any other info about the file you now have other methods to call and at that point, you lose the speed advantage anyway whilst having a solution that's harder to read.
The potential for speed is there but is not worth it unless you need to address such a bottleneck.
❌ I'd also rule out any ideas using substr, explode, and most other manual manipulations for the same reasons mentioned above.
❌SplFileInfo is very cool but takes up much more brain space 😝 with a lot of interfaces that you no doubt waste time learning only to look them up again next time. I'd only use it in specific cases where you will find the extra interfaces worth someone learning Spl when they come back to add/edit your code later.
❌ I would not consider preg_replace at all as any regex function in PHP is on average 3 times slower than any other function, is harder to read, and is in most cases can easily be done with something simpler. Regex is powerful and it has its place in those specific situations where it can replace several method calls and condition checks in one line.
Getting a file extension this way is like using an anvil to hammer in a nail.
While of course "the best" would come down to public opinion, I'd argue that other methods are only "the best" in specialized cases.
For example, if you just want to check for a specific type then I wouldn't use any of the suggested methods as stripos would be the fastest case insensitive comparison to use.
if (stripos('/here/is/sOme.fiLe.PdF', '.pdf', -4) !== false )
{
//its a pdf file
}
But again pathinfo would still be nicer to read and probably worth the performance cost.
But what about https://ome.Com.///lica.ted?URLS ?
Extracting paths from URLs is a separate concern that is outside the scope of the question and will require an extra step in any case where a simple one-time string comparison won't do.
Here is an example. Suppose $filename is "example.txt",
$ext = substr($filename, strrpos($filename, '.', -1), strlen($filename));
So $ext will be ".txt".
pathinfo is an array. We can check directory name, file name, extension, etc.:
$path_parts = pathinfo('test.png');
echo $path_parts['extension'], "\n";
echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['filename'], "\n";
substr($path, strrpos($path, '.') + 1);
A quick fix would be something like this.
// Exploding the file based on the . operator
$file_ext = explode('.', $filename);
// Count taken (if more than one . exist; files like abc.fff.2013.pdf
$file_ext_count = count($file_ext);
// Minus 1 to make the offset correct
$cnt = $file_ext_count - 1;
// The variable will have a value pdf as per the sample file name mentioned above.
$file_extension = $file_ext[$cnt];
I found that the pathinfo() and SplFileInfo solutions works well for standard files on the local file system, but you can run into difficulties if you're working with remote files as URLs for valid images may have a # (fragment identifiers) and/or ? (query parameters) at the end of the URL, which both those solutions will (incorrect) treat as part of the file extension.
I found this was a reliable way to use pathinfo() on a URL after first parsing it to strip out the unnecessary clutter after the file extension:
$url_components = parse_url($url); // First parse the URL
$url_path = $url_components['path']; // Then get the path component
$ext = pathinfo($url_path, PATHINFO_EXTENSION); // Then use pathinfo()
You can try also this:
pathinfo(basename($_FILES["fileToUpload"]["name"]), PATHINFO_EXTENSION)
IMO, this is the best way if you have filenames like name.name.name.ext (ugly, but it sometimes happens):
$ext = explode('.', $filename); // Explode the string
$my_ext = end($ext); // Get the last entry of the array
echo $my_ext;
Use substr($path, strrpos($path,'.')+1);. It is the fastest method of all compares.
#Kurt Zhong already answered.
Let's check the comparative result here: https://eval.in/661574
This will work
$ext = pathinfo($filename, PATHINFO_EXTENSION);
You can get all file extensions in a particular folder and do operations with a specific file extension:
<?php
$files = glob("abc/*.*"); // abc is the folder all files inside folder
//print_r($files);
//echo count($files);
for($i=0; $i<count($files); $i++):
$extension = pathinfo($files[$i], PATHINFO_EXTENSION);
$ext[] = $extension;
// Do operation for particular extension type
if($extension=='html'){
// Do operation
}
endfor;
print_r($ext);
?>
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $fileName);
preg_replace approach we using regular expression search and replace. In preg_replace function first parameter is pattern to the search, second parameter $1 is a reference to whatever is matched by the first (.*) and third parameter is file name.
Another way, we can also use strrpos to find the position of the last occurrence of a ‘.’ in a file name and increment that position by 1 so that it will explode string from (.)
$ext = substr($fileName, strrpos($fileName, '.') + 1);
ltrim(strstr($file_url, '.'), '.')
this is the best way if you have filenames like name.name.name.ext (ugly, but it sometimes happens
In one line:
pathinfo(parse_url($url,PHP_URL_PATH),PATHINFO_EXTENSION);
If you are looking for speed (such as in a router), you probably don't want to tokenize everything. Many other answers will fail with /root/my.folder/my.css
ltrim(strrchr($PATH, '.'),'.');
Although the "best way" is debatable, I believe this is the best way for a few reasons:
function getExt($path)
{
$basename = basename($path);
return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
It works with multiple parts to an extension, eg tar.gz
Short and efficient code
It works with both a filename and a complete path
Actually, I was looking for that.
<?php
$url = 'http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ';
$tmp = #parse_url($url)['path'];
$ext = pathinfo($tmp, PATHINFO_EXTENSION);
var_dump($ext);
I tried one simple solution it might help to someone else to get just filename from the URL which having get parameters
<?php
$path = "URL will be here";
echo basename(parse_url($path)['path']);
?>
Thanks
Related
This is a question you can read everywhere on the web with various answers:
$ext = end(explode('.', $filename));
$ext = substr(strrchr($filename, '.'), 1);
$ext = substr($filename, strrpos($filename, '.') + 1);
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $filename);
$exts = split("[/\\.]", $filename);
$n = count($exts)-1;
$ext = $exts[$n];
etc.
However, there is always "the best way" and it should be on Stack Overflow.
People from other scripting languages always think theirs is better because they have a built-in function to do that and not PHP (I am looking at Pythonistas right now :-)).
In fact, it does exist, but few people know it. Meet pathinfo():
$ext = pathinfo($filename, PATHINFO_EXTENSION);
This is fast and built-in. pathinfo() can give you other information, such as canonical path, depending on the constant you pass to it.
Remember that if you want to be able to deal with non ASCII characters, you need to set the locale first. E.G:
setlocale(LC_ALL,'en_US.UTF-8');
Also, note this doesn't take into consideration the file content or mime-type, you only get the extension. But it's what you asked for.
Lastly, note that this works only for a file path, not a URL resources path, which is covered using PARSE_URL.
Enjoy
pathinfo()
$path_info = pathinfo('/foo/bar/baz.bill');
echo $path_info['extension']; // "bill"
Example URL: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ
A) Don't use suggested unsafe PATHINFO:
pathinfo($url)['dirname'] 🡺 'http://example.com/myfolder'
pathinfo($url)['basename'] 🡺 'sympony.mp3?a=1&b=2#XYZ' // <------- BAD !!
pathinfo($url)['extension'] 🡺 'mp3?a=1&b=2#XYZ' // <------- BAD !!
pathinfo($url)['filename'] 🡺 'sympony'
B) Use PARSE_URL:
parse_url($url)['scheme'] 🡺 'http'
parse_url($url)['host'] 🡺 'example.com'
parse_url($url)['path'] 🡺 '/myfolder/sympony.mp3'
parse_url($url)['query'] 🡺 'aa=1&bb=2'
parse_url($url)['fragment'] 🡺 'XYZ'
BONUS: View all native PHP examples
There is also SplFileInfo:
$file = new SplFileInfo($path);
$ext = $file->getExtension();
Often you can write better code if you pass such an object around instead of a string. Your code is more speaking then. Since PHP 5.4 this is a one-liner:
$ext = (new SplFileInfo($path))->getExtension();
Do it faster!
In other words, if you only work with a filename, please stop using pathinfo.
I mean, sure if you have a full pathname, pathinfo makes sense because it's smarter than just finding dots: the path can contain dots and filename itself may have none. So in this case, considering an input string like d:/some.thing/myfile, pathinfo and other fully equipped methods are a good choice.
But if all you have is a filename, with no path, it's simply pointless to make the system work a lot more than it needs to. And this can give you a 10x speed boost.
Here's a quick speed test:
/* 387 ns */ function method1($s) {return preg_replace("/.*\./","",$s);} // edge case problem
/* 769 ns */ function method2($s) {preg_match("/\.([^\.]+)$/",$s,$a);return $a[1];}
/* 67 ns */ function method3($s) {$n = strrpos($s,"."); if($n===false) return "";return substr($s,$n+1);}
/* 175 ns */ function method4($s) {$a = explode(".",$s);$n = count($a); if($n==1) return "";return $a[$n-1];}
/* 731 ns */ function method5($s) {return pathinfo($s, PATHINFO_EXTENSION);}
/* 732 ns */ function method6($s) {return (new SplFileInfo($s))->getExtension();}
// All measured on Linux; it will be vastly different on Windows
Those nanosecond values will obviously differ on each system, but they give a clear picture about proportions. SplFileInfo and pathinfo are great fellas, but for this kind of job it's simply not worth it to wake them up. For the same reason, explode() is considerably faster than regex. Very simple tools tend to beat more sophisticated ones.
Conclusion
This seems to be the Way of the Samurai:
function fileExtension($name) {
$n = strrpos($name, '.');
return ($n === false) ? '' : substr($name, $n+1);
}
Remember this is for simple filenames only. If you have paths involved, stick to pathinfo or deal with the dirname separately.
E-satis's response is the correct way to determine the file extension.
Alternatively, instead of relying on a files extension, you could use the fileinfo to determine the files MIME type.
Here's a simplified example of processing an image uploaded by a user:
// Code assumes necessary extensions are installed and a successful file upload has already occurred
// Create a FileInfo object
$finfo = new FileInfo(null, '/path/to/magic/file');
// Determine the MIME type of the uploaded file
switch ($finfo->file($_FILES['image']['tmp_name'], FILEINFO_MIME)) {
case 'image/jpg':
$im = imagecreatefromjpeg($_FILES['image']['tmp_name']);
break;
case 'image/png':
$im = imagecreatefrompng($_FILES['image']['tmp_name']);
break;
case 'image/gif':
$im = imagecreatefromgif($_FILES['image']['tmp_name']);
break;
}
As long as it does not contain a path you can also use:
array_pop(explode('.', $fname))
Where $fname is a name of the file, for example: my_picture.jpg.
And the outcome would be: jpg
1) If you are using (PHP 5 >= 5.3.6)
you can use SplFileInfo::getExtension — Gets the file extension
Example code
<?php
$info = new SplFileInfo('test.png');
var_dump($info->getExtension());
$info = new SplFileInfo('test.tar.gz');
var_dump($info->getExtension());
?>
This will output
string(3) "png"
string(2) "gz"
2) Another way of getting the extension if you are using (PHP 4 >= 4.0.3, PHP 5) is pathinfo
Example code
<?php
$ext = pathinfo('test.png', PATHINFO_EXTENSION);
var_dump($ext);
$ext = pathinfo('test.tar.gz', PATHINFO_EXTENSION);
var_dump($ext);
?>
This will output
string(3) "png"
string(2) "gz"
// EDIT: removed a bracket
Sometimes it's useful to not to use pathinfo($path, PATHINFO_EXTENSION). For example:
$path = '/path/to/file.tar.gz';
echo ltrim(strstr($path, '.'), '.'); // tar.gz
echo pathinfo($path, PATHINFO_EXTENSION); // gz
Also note that pathinfo fails to handle some non-ASCII characters (usually it just suppresses them from the output). In extensions that usually isn't a problem, but it doesn't hurt to be aware of that caveat.
Sorry... "Short Question; But NOT Short Answer"
Example 1 for PATH
$path = "/home/ali/public_html/wp-content/themes/chicken/css/base.min.css";
$name = pathinfo($path, PATHINFO_FILENAME);
$ext = pathinfo($path, PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);
Example 2 for URL
$url = "//www.example.com/dir/file.bak.php?Something+is+wrong=hello";
$url = parse_url($url);
$name = pathinfo($url['path'], PATHINFO_FILENAME);
$ext = pathinfo($url['path'], PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);
Output of example 1:
Name: base.min
Extension: css
Output of example 2:
Name: file.bak
Extension: php
References
https://www.php.net/manual/en/function.pathinfo.php
https://www.php.net/manual/en/function.realpath.php
https://www.php.net/manual/en/function.parse-url.php
The simplest way to get file extension in PHP is to use PHP's built-in function pathinfo.
$file_ext = pathinfo('your_file_name_here', PATHINFO_EXTENSION);
echo ($file_ext); // The output should be the extension of the file e.g., png, gif, or html
You can try also this (it works on PHP 5.* and 7):
$info = new SplFileInfo('test.zip');
echo $info->getExtension(); // ----- Output -----> zip
Tip: it returns an empty string if the file doesn't have an extension
The "best" way depends on the context and what you are doing with that file extension.
However,
🥇 pathinfo in general is the best when you consider all the angles.
pathinfo($file, PATHINFO_EXTENSION)
It is not the fastest, but it is fast enough. It is easy to read, easy to remember and reuse everywhere. Anyone can understand it at a glance and remove PATHINFO_EXT flag if they need more info about the file.
❌ strrpos method. described in several answers is faster yes but requires additional safety checks which, in turn, requires you to wrap it inside a function, to make it easily reusable.
Then you must take the function with you from project to project or look it up.
Wrapping it in a function call with extra checks also makes it slower and if you need any other info about the file you now have other methods to call and at that point, you lose the speed advantage anyway whilst having a solution that's harder to read.
The potential for speed is there but is not worth it unless you need to address such a bottleneck.
❌ I'd also rule out any ideas using substr, explode, and most other manual manipulations for the same reasons mentioned above.
❌SplFileInfo is very cool but takes up much more brain space 😝 with a lot of interfaces that you no doubt waste time learning only to look them up again next time. I'd only use it in specific cases where you will find the extra interfaces worth someone learning Spl when they come back to add/edit your code later.
❌ I would not consider preg_replace at all as any regex function in PHP is on average 3 times slower than any other function, is harder to read, and is in most cases can easily be done with something simpler. Regex is powerful and it has its place in those specific situations where it can replace several method calls and condition checks in one line.
Getting a file extension this way is like using an anvil to hammer in a nail.
While of course "the best" would come down to public opinion, I'd argue that other methods are only "the best" in specialized cases.
For example, if you just want to check for a specific type then I wouldn't use any of the suggested methods as stripos would be the fastest case insensitive comparison to use.
if (stripos('/here/is/sOme.fiLe.PdF', '.pdf', -4) !== false )
{
//its a pdf file
}
But again pathinfo would still be nicer to read and probably worth the performance cost.
But what about https://ome.Com.///lica.ted?URLS ?
Extracting paths from URLs is a separate concern that is outside the scope of the question and will require an extra step in any case where a simple one-time string comparison won't do.
Here is an example. Suppose $filename is "example.txt",
$ext = substr($filename, strrpos($filename, '.', -1), strlen($filename));
So $ext will be ".txt".
pathinfo is an array. We can check directory name, file name, extension, etc.:
$path_parts = pathinfo('test.png');
echo $path_parts['extension'], "\n";
echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['filename'], "\n";
substr($path, strrpos($path, '.') + 1);
A quick fix would be something like this.
// Exploding the file based on the . operator
$file_ext = explode('.', $filename);
// Count taken (if more than one . exist; files like abc.fff.2013.pdf
$file_ext_count = count($file_ext);
// Minus 1 to make the offset correct
$cnt = $file_ext_count - 1;
// The variable will have a value pdf as per the sample file name mentioned above.
$file_extension = $file_ext[$cnt];
I found that the pathinfo() and SplFileInfo solutions works well for standard files on the local file system, but you can run into difficulties if you're working with remote files as URLs for valid images may have a # (fragment identifiers) and/or ? (query parameters) at the end of the URL, which both those solutions will (incorrect) treat as part of the file extension.
I found this was a reliable way to use pathinfo() on a URL after first parsing it to strip out the unnecessary clutter after the file extension:
$url_components = parse_url($url); // First parse the URL
$url_path = $url_components['path']; // Then get the path component
$ext = pathinfo($url_path, PATHINFO_EXTENSION); // Then use pathinfo()
You can try also this:
pathinfo(basename($_FILES["fileToUpload"]["name"]), PATHINFO_EXTENSION)
IMO, this is the best way if you have filenames like name.name.name.ext (ugly, but it sometimes happens):
$ext = explode('.', $filename); // Explode the string
$my_ext = end($ext); // Get the last entry of the array
echo $my_ext;
Use substr($path, strrpos($path,'.')+1);. It is the fastest method of all compares.
#Kurt Zhong already answered.
Let's check the comparative result here: https://eval.in/661574
This will work
$ext = pathinfo($filename, PATHINFO_EXTENSION);
You can get all file extensions in a particular folder and do operations with a specific file extension:
<?php
$files = glob("abc/*.*"); // abc is the folder all files inside folder
//print_r($files);
//echo count($files);
for($i=0; $i<count($files); $i++):
$extension = pathinfo($files[$i], PATHINFO_EXTENSION);
$ext[] = $extension;
// Do operation for particular extension type
if($extension=='html'){
// Do operation
}
endfor;
print_r($ext);
?>
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $fileName);
preg_replace approach we using regular expression search and replace. In preg_replace function first parameter is pattern to the search, second parameter $1 is a reference to whatever is matched by the first (.*) and third parameter is file name.
Another way, we can also use strrpos to find the position of the last occurrence of a ‘.’ in a file name and increment that position by 1 so that it will explode string from (.)
$ext = substr($fileName, strrpos($fileName, '.') + 1);
ltrim(strstr($file_url, '.'), '.')
this is the best way if you have filenames like name.name.name.ext (ugly, but it sometimes happens
In one line:
pathinfo(parse_url($url,PHP_URL_PATH),PATHINFO_EXTENSION);
If you are looking for speed (such as in a router), you probably don't want to tokenize everything. Many other answers will fail with /root/my.folder/my.css
ltrim(strrchr($PATH, '.'),'.');
Although the "best way" is debatable, I believe this is the best way for a few reasons:
function getExt($path)
{
$basename = basename($path);
return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
It works with multiple parts to an extension, eg tar.gz
Short and efficient code
It works with both a filename and a complete path
Actually, I was looking for that.
<?php
$url = 'http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ';
$tmp = #parse_url($url)['path'];
$ext = pathinfo($tmp, PATHINFO_EXTENSION);
var_dump($ext);
I tried one simple solution it might help to someone else to get just filename from the URL which having get parameters
<?php
$path = "URL will be here";
echo basename(parse_url($path)['path']);
?>
Thanks
This is a question you can read everywhere on the web with various answers:
$ext = end(explode('.', $filename));
$ext = substr(strrchr($filename, '.'), 1);
$ext = substr($filename, strrpos($filename, '.') + 1);
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $filename);
$exts = split("[/\\.]", $filename);
$n = count($exts)-1;
$ext = $exts[$n];
etc.
However, there is always "the best way" and it should be on Stack Overflow.
People from other scripting languages always think theirs is better because they have a built-in function to do that and not PHP (I am looking at Pythonistas right now :-)).
In fact, it does exist, but few people know it. Meet pathinfo():
$ext = pathinfo($filename, PATHINFO_EXTENSION);
This is fast and built-in. pathinfo() can give you other information, such as canonical path, depending on the constant you pass to it.
Remember that if you want to be able to deal with non ASCII characters, you need to set the locale first. E.G:
setlocale(LC_ALL,'en_US.UTF-8');
Also, note this doesn't take into consideration the file content or mime-type, you only get the extension. But it's what you asked for.
Lastly, note that this works only for a file path, not a URL resources path, which is covered using PARSE_URL.
Enjoy
pathinfo()
$path_info = pathinfo('/foo/bar/baz.bill');
echo $path_info['extension']; // "bill"
Example URL: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ
A) Don't use suggested unsafe PATHINFO:
pathinfo($url)['dirname'] 🡺 'http://example.com/myfolder'
pathinfo($url)['basename'] 🡺 'sympony.mp3?a=1&b=2#XYZ' // <------- BAD !!
pathinfo($url)['extension'] 🡺 'mp3?a=1&b=2#XYZ' // <------- BAD !!
pathinfo($url)['filename'] 🡺 'sympony'
B) Use PARSE_URL:
parse_url($url)['scheme'] 🡺 'http'
parse_url($url)['host'] 🡺 'example.com'
parse_url($url)['path'] 🡺 '/myfolder/sympony.mp3'
parse_url($url)['query'] 🡺 'aa=1&bb=2'
parse_url($url)['fragment'] 🡺 'XYZ'
BONUS: View all native PHP examples
There is also SplFileInfo:
$file = new SplFileInfo($path);
$ext = $file->getExtension();
Often you can write better code if you pass such an object around instead of a string. Your code is more speaking then. Since PHP 5.4 this is a one-liner:
$ext = (new SplFileInfo($path))->getExtension();
Do it faster!
In other words, if you only work with a filename, please stop using pathinfo.
I mean, sure if you have a full pathname, pathinfo makes sense because it's smarter than just finding dots: the path can contain dots and filename itself may have none. So in this case, considering an input string like d:/some.thing/myfile, pathinfo and other fully equipped methods are a good choice.
But if all you have is a filename, with no path, it's simply pointless to make the system work a lot more than it needs to. And this can give you a 10x speed boost.
Here's a quick speed test:
/* 387 ns */ function method1($s) {return preg_replace("/.*\./","",$s);} // edge case problem
/* 769 ns */ function method2($s) {preg_match("/\.([^\.]+)$/",$s,$a);return $a[1];}
/* 67 ns */ function method3($s) {$n = strrpos($s,"."); if($n===false) return "";return substr($s,$n+1);}
/* 175 ns */ function method4($s) {$a = explode(".",$s);$n = count($a); if($n==1) return "";return $a[$n-1];}
/* 731 ns */ function method5($s) {return pathinfo($s, PATHINFO_EXTENSION);}
/* 732 ns */ function method6($s) {return (new SplFileInfo($s))->getExtension();}
// All measured on Linux; it will be vastly different on Windows
Those nanosecond values will obviously differ on each system, but they give a clear picture about proportions. SplFileInfo and pathinfo are great fellas, but for this kind of job it's simply not worth it to wake them up. For the same reason, explode() is considerably faster than regex. Very simple tools tend to beat more sophisticated ones.
Conclusion
This seems to be the Way of the Samurai:
function fileExtension($name) {
$n = strrpos($name, '.');
return ($n === false) ? '' : substr($name, $n+1);
}
Remember this is for simple filenames only. If you have paths involved, stick to pathinfo or deal with the dirname separately.
As long as it does not contain a path you can also use:
array_pop(explode('.', $fname))
Where $fname is a name of the file, for example: my_picture.jpg.
And the outcome would be: jpg
E-satis's response is the correct way to determine the file extension.
Alternatively, instead of relying on a files extension, you could use the fileinfo to determine the files MIME type.
Here's a simplified example of processing an image uploaded by a user:
// Code assumes necessary extensions are installed and a successful file upload has already occurred
// Create a FileInfo object
$finfo = new FileInfo(null, '/path/to/magic/file');
// Determine the MIME type of the uploaded file
switch ($finfo->file($_FILES['image']['tmp_name'], FILEINFO_MIME)) {
case 'image/jpg':
$im = imagecreatefromjpeg($_FILES['image']['tmp_name']);
break;
case 'image/png':
$im = imagecreatefrompng($_FILES['image']['tmp_name']);
break;
case 'image/gif':
$im = imagecreatefromgif($_FILES['image']['tmp_name']);
break;
}
1) If you are using (PHP 5 >= 5.3.6)
you can use SplFileInfo::getExtension — Gets the file extension
Example code
<?php
$info = new SplFileInfo('test.png');
var_dump($info->getExtension());
$info = new SplFileInfo('test.tar.gz');
var_dump($info->getExtension());
?>
This will output
string(3) "png"
string(2) "gz"
2) Another way of getting the extension if you are using (PHP 4 >= 4.0.3, PHP 5) is pathinfo
Example code
<?php
$ext = pathinfo('test.png', PATHINFO_EXTENSION);
var_dump($ext);
$ext = pathinfo('test.tar.gz', PATHINFO_EXTENSION);
var_dump($ext);
?>
This will output
string(3) "png"
string(2) "gz"
// EDIT: removed a bracket
Sometimes it's useful to not to use pathinfo($path, PATHINFO_EXTENSION). For example:
$path = '/path/to/file.tar.gz';
echo ltrim(strstr($path, '.'), '.'); // tar.gz
echo pathinfo($path, PATHINFO_EXTENSION); // gz
Also note that pathinfo fails to handle some non-ASCII characters (usually it just suppresses them from the output). In extensions that usually isn't a problem, but it doesn't hurt to be aware of that caveat.
Sorry... "Short Question; But NOT Short Answer"
Example 1 for PATH
$path = "/home/ali/public_html/wp-content/themes/chicken/css/base.min.css";
$name = pathinfo($path, PATHINFO_FILENAME);
$ext = pathinfo($path, PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);
Example 2 for URL
$url = "//www.example.com/dir/file.bak.php?Something+is+wrong=hello";
$url = parse_url($url);
$name = pathinfo($url['path'], PATHINFO_FILENAME);
$ext = pathinfo($url['path'], PATHINFO_EXTENSION);
printf('<hr> Name: %s <br> Extension: %s', $name, $ext);
Output of example 1:
Name: base.min
Extension: css
Output of example 2:
Name: file.bak
Extension: php
References
https://www.php.net/manual/en/function.pathinfo.php
https://www.php.net/manual/en/function.realpath.php
https://www.php.net/manual/en/function.parse-url.php
The simplest way to get file extension in PHP is to use PHP's built-in function pathinfo.
$file_ext = pathinfo('your_file_name_here', PATHINFO_EXTENSION);
echo ($file_ext); // The output should be the extension of the file e.g., png, gif, or html
You can try also this (it works on PHP 5.* and 7):
$info = new SplFileInfo('test.zip');
echo $info->getExtension(); // ----- Output -----> zip
Tip: it returns an empty string if the file doesn't have an extension
The "best" way depends on the context and what you are doing with that file extension.
However,
🥇 pathinfo in general is the best when you consider all the angles.
pathinfo($file, PATHINFO_EXTENSION)
It is not the fastest, but it is fast enough. It is easy to read, easy to remember and reuse everywhere. Anyone can understand it at a glance and remove PATHINFO_EXT flag if they need more info about the file.
❌ strrpos method. described in several answers is faster yes but requires additional safety checks which, in turn, requires you to wrap it inside a function, to make it easily reusable.
Then you must take the function with you from project to project or look it up.
Wrapping it in a function call with extra checks also makes it slower and if you need any other info about the file you now have other methods to call and at that point, you lose the speed advantage anyway whilst having a solution that's harder to read.
The potential for speed is there but is not worth it unless you need to address such a bottleneck.
❌ I'd also rule out any ideas using substr, explode, and most other manual manipulations for the same reasons mentioned above.
❌SplFileInfo is very cool but takes up much more brain space 😝 with a lot of interfaces that you no doubt waste time learning only to look them up again next time. I'd only use it in specific cases where you will find the extra interfaces worth someone learning Spl when they come back to add/edit your code later.
❌ I would not consider preg_replace at all as any regex function in PHP is on average 3 times slower than any other function, is harder to read, and is in most cases can easily be done with something simpler. Regex is powerful and it has its place in those specific situations where it can replace several method calls and condition checks in one line.
Getting a file extension this way is like using an anvil to hammer in a nail.
While of course "the best" would come down to public opinion, I'd argue that other methods are only "the best" in specialized cases.
For example, if you just want to check for a specific type then I wouldn't use any of the suggested methods as stripos would be the fastest case insensitive comparison to use.
if (stripos('/here/is/sOme.fiLe.PdF', '.pdf', -4) !== false )
{
//its a pdf file
}
But again pathinfo would still be nicer to read and probably worth the performance cost.
But what about https://ome.Com.///lica.ted?URLS ?
Extracting paths from URLs is a separate concern that is outside the scope of the question and will require an extra step in any case where a simple one-time string comparison won't do.
Here is an example. Suppose $filename is "example.txt",
$ext = substr($filename, strrpos($filename, '.', -1), strlen($filename));
So $ext will be ".txt".
pathinfo is an array. We can check directory name, file name, extension, etc.:
$path_parts = pathinfo('test.png');
echo $path_parts['extension'], "\n";
echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['filename'], "\n";
substr($path, strrpos($path, '.') + 1);
A quick fix would be something like this.
// Exploding the file based on the . operator
$file_ext = explode('.', $filename);
// Count taken (if more than one . exist; files like abc.fff.2013.pdf
$file_ext_count = count($file_ext);
// Minus 1 to make the offset correct
$cnt = $file_ext_count - 1;
// The variable will have a value pdf as per the sample file name mentioned above.
$file_extension = $file_ext[$cnt];
I found that the pathinfo() and SplFileInfo solutions works well for standard files on the local file system, but you can run into difficulties if you're working with remote files as URLs for valid images may have a # (fragment identifiers) and/or ? (query parameters) at the end of the URL, which both those solutions will (incorrect) treat as part of the file extension.
I found this was a reliable way to use pathinfo() on a URL after first parsing it to strip out the unnecessary clutter after the file extension:
$url_components = parse_url($url); // First parse the URL
$url_path = $url_components['path']; // Then get the path component
$ext = pathinfo($url_path, PATHINFO_EXTENSION); // Then use pathinfo()
You can try also this:
pathinfo(basename($_FILES["fileToUpload"]["name"]), PATHINFO_EXTENSION)
IMO, this is the best way if you have filenames like name.name.name.ext (ugly, but it sometimes happens):
$ext = explode('.', $filename); // Explode the string
$my_ext = end($ext); // Get the last entry of the array
echo $my_ext;
Use substr($path, strrpos($path,'.')+1);. It is the fastest method of all compares.
#Kurt Zhong already answered.
Let's check the comparative result here: https://eval.in/661574
This will work
$ext = pathinfo($filename, PATHINFO_EXTENSION);
You can get all file extensions in a particular folder and do operations with a specific file extension:
<?php
$files = glob("abc/*.*"); // abc is the folder all files inside folder
//print_r($files);
//echo count($files);
for($i=0; $i<count($files); $i++):
$extension = pathinfo($files[$i], PATHINFO_EXTENSION);
$ext[] = $extension;
// Do operation for particular extension type
if($extension=='html'){
// Do operation
}
endfor;
print_r($ext);
?>
$ext = preg_replace('/^.*\.([^.]+)$/D', '$1', $fileName);
preg_replace approach we using regular expression search and replace. In preg_replace function first parameter is pattern to the search, second parameter $1 is a reference to whatever is matched by the first (.*) and third parameter is file name.
Another way, we can also use strrpos to find the position of the last occurrence of a ‘.’ in a file name and increment that position by 1 so that it will explode string from (.)
$ext = substr($fileName, strrpos($fileName, '.') + 1);
ltrim(strstr($file_url, '.'), '.')
this is the best way if you have filenames like name.name.name.ext (ugly, but it sometimes happens
In one line:
pathinfo(parse_url($url,PHP_URL_PATH),PATHINFO_EXTENSION);
If you are looking for speed (such as in a router), you probably don't want to tokenize everything. Many other answers will fail with /root/my.folder/my.css
ltrim(strrchr($PATH, '.'),'.');
Although the "best way" is debatable, I believe this is the best way for a few reasons:
function getExt($path)
{
$basename = basename($path);
return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
It works with multiple parts to an extension, eg tar.gz
Short and efficient code
It works with both a filename and a complete path
Actually, I was looking for that.
<?php
$url = 'http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ';
$tmp = #parse_url($url)['path'];
$ext = pathinfo($tmp, PATHINFO_EXTENSION);
var_dump($ext);
I tried one simple solution it might help to someone else to get just filename from the URL which having get parameters
<?php
$path = "URL will be here";
echo basename(parse_url($path)['path']);
?>
Thanks
I'm writing an image upload script and have whitelisted common image extensions. I need to be able to get the extension of files to determine if they are in the whitelist, but I'm having trouble with some URLs.
Here is an example:
http://pisces.bbystatic.com/image/BestBuy_US/images/products/5512/5512124_ra.jpg;canvasHeight=280;canvasWidth=280
My code:
echo pathinfo($url, PATHINFO_EXTENSION);
Outputs the following:
jpg;canvasHeight=280;canvasWidth=280
DEMO
I could change my code to this, which fixes the problem:
$parts = explode(';', pathinfo($url, PATHINFO_EXTENSION));
echo $parts[0];
DEMO
However, I don't know if that is the best approach to take here (for one thing, because other websites might use different delimiters for data instead of a semicolon);
Is there a better way?
EDIT: It might be worth noting that I tried uploading the image here as a test (using the example URL) and StackOverflow had no trouble uploading it.
Using pathinfo() only will match cases like http://google.com -> com. Use parse_url first to safely get the URL path, then use pathinfo to get the file extension.
If the URL uses query strings (e.g. ?foo=bar), that code should be enough. But given your example wherein the URL uses some custom format instead of query strings, you can use RegEx to select only the first alphanumeric part of $ext.
$url = 'http://pisces.bbystatic.com/image/BestBuy_US/images/products/5512/5512124_ra.jpg;canvasHeight=280;canvasWidth=280';
$ext = pathinfo(parse_url($url, PHP_URL_PATH), PATHINFO_EXTENSION);
if (!empty($ext)) {
preg_match('/[a-zA-Z0-9]+/', $ext, $matches);
$ext = $matches[0];
}
echo $ext;
I need help about file manipulation in PHP.
I have 4 file with known names and UNKNOWN extensions.
Like that:
Y923BBBB.E120506
Y924BBBB.E120606
Y925BBBB.E120706
Y926BBBB.E120806
and the file extensions changes everyday.
How i can cut or strip for every file the file extension, so that will stay only the names like that:
Y923BBBB
Y924BBBB
Y925BBBB
Y926BBBB
Anybody an idea?
Think about it the other way around: you want to extract the filename, not "delete the extension":
echo pathinfo($file, PATHINFO_FILENAME);
http://php.net/pathinfo
Use strrpos to find the last . and substr to get only the substring up to that point. To find the files and rename them, use glob and rename:
foreach(glob('*') as $f) {
if ($f == '.' || $f == '..') continue;
$stripped = substr($f, 0, strrpos($f, '.'));
rename($f, $stripped);
}
Take care that glob('*') works differently on windows and linux (compare with answer). Use DirectoryIterator instead if you want a more stable code. Also that one provides the needed functions already to process the file-extension and won't break - as in this example - when a file does not have a dot inside. And take real care with rename, using glob returns the file-name only, rename handles this as full path, you will move files to locations you might not want to move them.
foreach(new DirectoryIterator('.') as $f) {
/* #var $f splFileInfo*/
if (!$f->isFile()) continue;
($ext = strlen($f->getExtension())) && $ext++;
if (!$ext) continue;
$path = $f->getRealPath();
rename($path, substr($path, 0, -$ext));
}
Take care. You should always takes care with rename operations. Every operation related to the file-system and changing it needs more care as let's say read-only proceedings.
I tried function: strstr, but it has one problem. Suppose, the URL looks like:
http://www.example.com/index.php
With strstr, I am able to remove anything before '/', but I want just:
index
i.e., the actual name of the file without extension.
I would highly suggest using the PHP parse_url() function:
$address = 'http://www.example.com/index.php';
$url = parse_url($address);
echo $url['host'];
There is no point reinventing the wheel.
If the file type can change and you are sure there are no other . in the file name e.g. index.2.php then you can use
$filename = basename('http://www.example.com/index.php');
$filename = substr($filename, 0, strpos($filename, '.'));
If it always ends in .php you can do:
basename('http://www.example.com/index.php', '.php')
If it can end with other extensions, you can do:
if (preg_match('#([^/]+)\.\w+$#', 'http://www.example.com/index.php', $matches))
$basename = $matches[1];
+1 cletus for the right tool for the right job, a proper URL parser. The regex hacks will fail for various query string stuff.
However it's the last path part being sought here not the host. So:
$url = parse_url($address);
$filename= array_pop(explode('/', $url['path']));
$filestem= explode('.', $filename)[0];
its very simple , no need for much code.
just do it manually and it will be automatically readed
just write your url like that
http://www.example.com/index
and it will show your files as there is .php in the end.