Как найти расширение файла в php

(PHP 4 >= 4.0.3, PHP 5, PHP 7, PHP 8)

pathinfoReturns information about a file path

Description

pathinfo(string $path, int $flags = PATHINFO_ALL): array|string

Note:

For information on retrieving the current path info, read
the section on
predefined reserved variables.

Note:

pathinfo() operates naively on the input string,
and is not aware of the actual filesystem, or path components such
as “..“.

Caution

pathinfo() is locale aware, so for it to parse a path
containing multibyte characters correctly, the matching locale must be set using
the setlocale() function.

Parameters

path

The path to be parsed.

flags

If present, specifies a specific element to be returned; one of
PATHINFO_DIRNAME,
PATHINFO_BASENAME,
PATHINFO_EXTENSION or
PATHINFO_FILENAME.

If flags is not specified, returns all
available elements.

Return Values

If the flags parameter is not passed, an
associative array containing the following elements is
returned:
dirname, basename,
extension (if any), and filename.

Note:

If the path has more than one extension,
PATHINFO_EXTENSION returns only the last one and
PATHINFO_FILENAME only strips the last one.
(see first example below).

Note:

If the path does not have an extension, no
extension element will be returned
(see second example below).

Note:

If the basename of the path starts
with a dot, the following characters are interpreted as
extension, and the filename is empty
(see third example below).

If flags is present, returns a
string containing the requested element.

Examples

Example #1 pathinfo() Example


<?php
$path_parts
= pathinfo('/www/htdocs/inc/lib.inc.php');

echo

$path_parts['dirname'], "n";
echo
$path_parts['basename'], "n";
echo
$path_parts['extension'], "n";
echo
$path_parts['filename'], "n";
?>

The above example will output:

/www/htdocs/inc
lib.inc.php
php
lib.inc

Example #2 pathinfo() example showing difference between null and no extension


<?php
$path_parts
= pathinfo('/path/emptyextension.');
var_dump($path_parts['extension']);$path_parts = pathinfo('/path/noextension');
var_dump($path_parts['extension']);
?>

The above example will output
something similar to:

string(0) ""

Notice: Undefined index: extension in test.php on line 6
NULL

Example #3 pathinfo() example for a dot-file


<?php
print_r
(pathinfo('/some/path/.test'));
?>

The above example will output
something similar to:

Array
(
    [dirname] => /some/path
    [basename] => .test
    [extension] => test
    [filename] => 
)

See Also

  • dirname() – Returns a parent directory’s path
  • basename() – Returns trailing name component of path
  • parse_url() – Parse a URL and return its components
  • realpath() – Returns canonicalized absolute pathname

Lori

4 years ago


Simple example of pathinfo and array destructuring in PHP 7:
<?php
[ 'basename' => $basename, 'dirname' => $dirname ] = pathinfo('/www/htdocs/inc/lib.inc.php');var_dump($basename, $dirname);// result:
// string(11) "lib.inc.php"
// string(15) "/www/htdocs/inc"
?>

Pietro Baricco

11 years ago


Use this function in place of pathinfo to make it work with UTF-8 encoded file names too

<?php
function mb_pathinfo($filepath) {
   
preg_match('%^(.*?)[\\/]*(([^/\\]*?)(.([^.\\/]+?)|))[\\/.]*$%im',$filepath,$m);
    if(
$m[1]) $ret['dirname']=$m[1];
    if(
$m[2]) $ret['basename']=$m[2];
    if(
$m[5]) $ret['extension']=$m[5];
    if(
$m[3]) $ret['filename']=$m[3];
    return
$ret;
}
?>


n0dalus

18 years ago


If a file has more than one 'file extension' (seperated by periods), the last one will be returned.
For example:
<?php
$pathinfo
= pathinfo('/dir/test.tar.gz');
echo
'Extension: '.$pathinfo['extension'];
?>
will produce:
Extension: gz

and not tar.gz


urvi

9 months ago


about the path, there are one thing you should note :
On Windows, both slash (/) and backslash () are used as directory separator character. In other environments, it is the forward slash (/).  (this explain is from basename() function part https://www.php.net/manual/en/function.basename.php)
example:
<?php
$path
= "https://urvidutta.com /abcfilename.pdf";

echo

pathinfo($pdfUrl, PATHINFO_BASENAME);  //get basename
//output
//on window:  result is filename.pdf
//on Linux: result is abcfilename.pdf (that is may not your expect)

//so in order to get same result in different system.  i will do below first.

$path = str_replace($path, '\', '/'); //convert ''  to '/'
?>

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.

Can We find out the extension of the original file from $_FILES["file"]["tmp_name"] ? For example jpg or png etc?

Machavity's user avatar

Machavity

30.7k27 gold badges91 silver badges100 bronze badges

asked Mar 25, 2011 at 0:25

Peter's user avatar

0

$name = $_FILES["file"]["name"];
$ext = end((explode(".", $name))); # extra () to prevent notice

echo $ext;

answered Mar 25, 2011 at 0:26

Dejan Marjanović's user avatar

Dejan MarjanovićDejan Marjanović

19.2k7 gold badges51 silver badges66 bronze badges

6

You could use pathinfo():

$path_parts = pathinfo($_FILES["file"]["name"]);
$extension = $path_parts['extension'];

John Ballinger's user avatar

answered Mar 25, 2011 at 0:29

JKS's user avatar

JKSJKS

3,7002 gold badges28 silver badges40 bronze badges

4

Yes you can use $_FILES['file']['name'] to get the original name of the uploaded file. Just keep in mind that the extension may not always represent the real contents of the file.

answered Mar 25, 2011 at 0:27

GWW's user avatar

GWWGWW

42.9k11 gold badges113 silver badges108 bronze badges

2

Yes, assuming it’s accurately named. It will retain its original name and extension.

answered Mar 25, 2011 at 0:28

thf's user avatar

thfthf

5841 gold badge10 silver badges22 bronze badges

Для поиска файлов на сервере хорошо подходит функция glob(), которая возвращает список файлов по заданной маске, например:

$files = glob('/tmp/*.jpg');

PHP

В маске можно использовать следующие специальные символы:

* Соответствует нулю или большему количеству любых символов.
? Один любой символ.
[...] Один символ входящий в группу.
[!...] Один символ не входящий в группу.
{...,...} Вхождение подстрок, работает с флагом GLOB_BRACE.
Экранирует следующий символ, кроме случаев, когда используется флаг GLOB_NOESCAPE.

Доступные флаги:

GLOB_MARK Добавляет слеш к каждой возвращаемой директории.
GLOB_NOSORT Возвращает файлы в том виде, в котором они содержатся в директории (без сортировки). Если этот флаг не указан, то имена сортируются по алфавиту.
GLOB_NOCHECK Возвращает шаблон поиска, если с его помощью не был найден ни один файл.
GLOB_NOESCAPE Обратные слеши не экранируют метасимволы.
GLOB_BRACE Раскрывает {a,b,c} для совпадения с «a», «b» или «c».
GLOB_ONLYDIR Возвращает только директории, совпадающие с шаблоном.
GLOB_ERR Останавливается при ошибках чтения (например, директории без права чтения), по умолчанию ошибки игнорируются.

Возможно использовать несколько флагов:

$files = glob('/tmp/*.jpg', GLOB_NOSORT|GLOB_ERR);

PHP

Далее во всех примерах используется папка tmp со следующим содержимым:

Содержимое папки tmp

1

Поиск в директории

Список всех файлов и директорий

$dir = __DIR__ . '/tmp';
 
$files = array();
foreach(glob($dir . '/*') as $file) {
	$files[] = basename($file);	
} 
 
print_r($files);

PHP

Результат:

Array
(
    [0] => 1.svg
    [1] => 2.jpg
    [2] => 22-f.gif
    [3] => 22.svg
    [4] => img.png
    [5] => path
    [6] => prod.png
    [7] => style-1.txt
    [8] => style-2.css
)

Только файлы

$dir = __DIR__ . '/tmp';

$files = array();
foreach(glob($dir . '/*') as $file) {
	if (is_file($file)) {
		$files[] = basename($file);	
	}
} 

print_r($files);

PHP

Результат:

Array
(
    [0] => 1.svg
    [1] => 2.jpg
    [2] => 22-f.gif
    [3] => 22.svg
    [4] => img.png
    [5] => prod.png
    [6] => style-1.txt
    [7] => style-2.css
)

Только директории

$dir = __DIR__ . '/tmp';

$files = array();
foreach(glob($dir . '/*') as $file) {
	if (is_dir($file)) {
		$files[] = basename($file);	
	}
} 

print_r($files);

PHP

Результат:

Array
(
    [0] => path
)

Поиск по расширению

$dir = __DIR__ . '/tmp';

$files = array();
foreach(glob($dir . '/*.svg') as $file) {
	$files[] = basename($file);	
} 

print_r($files);

PHP

Результат:

Array
(
    [0] => 1.svg
    [1] => 22.svg
)

Поиск по нескольким расширениям

$dir = __DIR__ . '/tmp';

$files = array();
foreach(glob($dir . '/*.{jpg,png}', GLOB_BRACE) as $file) {
	$files[] = basename($file);	
} 

print_r($files);

PHP

Результат:

Array
(
    [0] => 2.jpg
    [1] => img.png
    [2] => prod.png
)

Поиск по имени файла

Например, в названия файлов начинаются со слова «style»:

$dir = __DIR__ . '/tmp';

$files = array();
foreach(glob($dir . '/style*.*') as $file) {
	$files[] = basename($file);	
} 

print_r($files);

PHP

Результат:

Array
(
    [0] => style-1.txt
    [1] => style-2.css
)

Или начинаются с цифр:

$dir = __DIR__ . '/tmp';

$files = array();
foreach(glob($dir . '/[0-9]*.*', GLOB_BRACE) as $obj) {
	$files[] = basename($obj);	
} 

print_r($files);

PHP

Результат:

Array
(
    [0] => 1.svg
    [1] => 2.jpg
    [2] => 22-f.gif
    [3] => 22.svg
)

2

Поиск в дереве

Поиск по всем подкатегориям более сложный т.к. требует применение рекурсии.

Список всех файлов

function glob_tree_files($path, $_base_path = null)
{
	if (is_null($_base_path)) {
		$_base_path = '';
	} else {
		$_base_path .= basename($path) . '/';
	}

	$out = array();
	foreach(glob($path . '/*') as $file) {
		if (is_dir($file)) {
			$out = array_merge($out, glob_tree_files($file, $_base_path));
		} else {
			$out[] = $_base_path . basename($file);
		}
	}
 
	return $out;
}

$dir = __DIR__ . '/tmp';
$files = glob_tree_files($dir);
print_r($files);

PHP

Результат:

Array
(
    [0] => 1.svg
    [1] => 2.jpg
    [2] => 22-f.gif
    [3] => 22.svg
    [4] => img.png
    [5] => path/icon-rew.png
    [6] => path/marker.png
    [7] => path/psd/1.psd
    [8] => path/psd/2.psd
    [9] => path/psd/index.psd
    [10] => path/sh-1.png
    [11] => path/title-1.png
    [12] => prod.png
    [13] => style-1.txt
    [14] => style-2.css
)

Список всех директорий

function glob_tree_dirs($path, $_base_path = null)
{
	if (is_null($_base_path)) {
		$_base_path = '';
	} else {
		$_base_path .= basename($path) . '/';
	}

	$out = array();
	foreach(glob($path . '/*', GLOB_ONLYDIR) as $file) {
		if (is_dir($file)) {
			$out[] = $_base_path . basename($file);
			$out = array_merge($out, glob_tree_dirs($file, $_base_path));
		}
	}
 
	return $out;
}

$dir = __DIR__ . '/tmp';
$files = glob_tree_dirs($dir);
print_r($files);

PHP

Результат:

Array
(
    [0] => path
    [1] => path/psd
)

Поиск по имени/расширению

function glob_tree_search($path, $pattern, $_base_path = null)
{
	if (is_null($_base_path)) {
		$_base_path = '';
	} else {
		$_base_path .= basename($path) . '/';
	}

	$out = array();
	foreach(glob($path . '/' . $pattern, GLOB_BRACE) as $file) {
		$out[] = $_base_path . basename($file);
	}
	
	foreach(glob($path . '/*', GLOB_ONLYDIR) as $file) {
		$out = array_merge($out, glob_tree_search($file, $pattern, $_base_path));
	}

	return $out;
}

$path = __DIR__ . '/tmp';
$files = glob_tree_search($path, '*.{jpg,png}');
print_r($files);

PHP

Результат:

Array
(
    [0] => 2.jpg
    [1] => img.png
    [2] => prod.png
    [3] => path/icon-rew.png
    [4] => path/marker.png
    [5] => path/sh-1.png
    [6] => path/title-1.png
)

Чтобы в результирующих списках выводились полные пути к файлам, достаточно удалить функцию basename().

Другие публикации

Использование API Яндекс Диска на PHP

Можно найти множество применений Яндекс Диска на своем сайте, например, хранение бекапов и отчетов, обновление прайсов,…

Работа с FTP в PHP

Протокол FTP – предназначен для передачи файлов на удаленный хост. В PHP функции для работы с FTP как правило всегда доступны и не требуется установка дополнительного расширения.

Загрузка файлов на сервер PHP

В статье приведен пример формы и php-скрипта для безопасной загрузки файлов на сервер, возможные ошибки и рекомендации при работе с данной темой.

Пример парсинга html-страницы на phpQuery

phpQuery – это удобный HTML парсер взявший за основу селекторы, фильтры и методы jQuery, которые позволяют…

Поиск похожих текстов в базе данных MySQL + PHP

Один из вариантов поиска похожих статей в базе данных основан на схождении слов в двух текстах.

Список MIME типов

Ниже приведён список MIME-заголовков и расширений файлов.

Задача определения расширения возникает в разработке достаточно часто – здесь и загрузка файлов на сервер, и анализ имеющихся файлов, и поиск файла. В работе с файлами на сервере, есть так же частое решение сохранения файла не с исходным именем, а назначение в качестве имени файла текущего значения TIMESTAMP сервера. Решений у этой задачи существует немало для разных языков программирования. Хотя некоторые решения, в первую очередь, приходящие на ум, иногда приходится дорабатывать из-за того разнообразия имен файлов которые только могут быть. Для файла с именем “myfile.txt” можно смело предложить разбить строку на части разделенные точкой и взять последнюю. Но что делать с файлами “my.file.txt” или в случае, если расширение не указано “myfile”?

В этой статье, рассмотрим такие решения.

Для удобства имя файл зададим в строковой переменной:


    $filename = 'myfile.txt';

    // другие варианты имени файла
    $filename = 'file'; // не указано расширение
    $filename = 'my.file.txt'; // точка в имени файла
    $filename = 'dir/myfile.txt'; // имя файла с указанием директории
?>

Самое простое и удобное, на мой взгляд, решение использовать с, которая вернет ассоциированный массив, содержащий сведения полном имени, расширении и директории файла. После этого остается только вывести необходимый элемент массива.


   function get_file_extension($filename) {
      $file_info = pathinfo($filename);
      return $file_info['extension'];
   }

   echo get_file_extension($filename);
?>

Чтобы не делать собственную функцию можно упросить код, указав в качестве второго параметра значение PATHINFO_EXTENSION. В этом случае функция вернет не весь массив, а только значение расширения.


   echo pathinfo($filename, PATHINFO_EXTENSION);
?>

Оба варианта корректно вернут значение расширения “txt”, кроме случая, где расширение не указано. Там, где расширения нет, будет возвращена пустая строка.

Это решение доступно для PHP, начиная с версии 4.0.3.

Если по причине версии PHP или какой-либо другой причине это решение не доступно, можно использовать традиционное решение – разбивку строки имени файла на части между точками, считая, что последний участок и будет расширением.


   function get_file_extension($filename) {
   return end(explode(".", $filename));
   }

   echo get_file_extension($filename);
?>

Здесь, функция explode() разбивает строку на массив из символов, разделенных точками, а функция end() возвращает последний элемент полученного массива.

В этом примере, если расширение не задано явно, т.е. точки в имени файла нет, будет возвращено исходное имя файла. В случае, если расширение есть, оно будет получено корректно.

Добавить комментарий