Как получить расширение файла в PHP?

Это вопрос, который вы можете прочитать повсюду в Интернете с различными ответами:

$ext = end(explode('.', $filename));
$ext = substr(strrchr($filename, '.'), 1);
$ext = substr($filename, strrpos($filename, '.') + 1);
$ext = preg_replace('/^.*\.([^.]+)$/D', '', $filename);

$exts = split("[/\.]", $filename);
$n    = count($exts)-1;
$ext  = $exts[$n];

и т.п.

Однако всегда есть «лучший способ», и он должен быть в Stack Overflow.

Источник вопроса и ответа: cowburn.info/2008/01/13/get-file-extension-comparison

salathe 26.03.2011 16:37

Еще один способ получить ext - strrchr($filename, '.');.

verybadbug 30.09.2013 09:06

strrpos - правильный способ (см. мой ответ), но для случая без расширения он нуждается в дополнении.

dkellner 04.10.2020 18:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
767
3
645 027
29
Перейти к ответу Данный вопрос помечен как решенный

Ответы 29

pathinfo()

$path_info = pathinfo('/foo/bar/baz.bill');

echo $path_info['extension']; // "bill"

Начиная с PHP 5.5 -> echo pathinfo('/foo/bar/baz.bill')['extension'];

Salman A 13.09.2014 16:18

Это работает даже на этом уровне (Twitter json): $ ext = pathinfo ($ result-> extended_entities-> media [0] -> video_info-> v‌ ariants [1] -> url, PATHINFO_EXTENSION);

KJS 04.12.2016 04:01
Ответ принят как подходящий

Люди из других языков сценариев всегда думают, что их язык лучше, потому что для этого у них есть встроенная функция, а не PHP (сейчас я смотрю на Pythonistas :-)).

На самом деле он существует, но мало кто об этом знает. Встречайте pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Это быстро и встроено. pathinfo() может предоставить вам другую информацию, например канонический путь, в зависимости от константы, которую вы ему передаете.

Помните, что если вы хотите иметь возможность работать с символами, отличными от ASCII, вам необходимо сначала установить языковой стандарт. НАПРИМЕР:

setlocale(LC_ALL,'en_US.UTF-8');

Также обратите внимание, что это не принимает во внимание содержимое файла или тип mime, вы получаете только расширение. Но это то, о чем вы просили.

Наконец, обратите внимание, что это работает только для пути к файлу, а не для пути к ресурсам URL, который покрывается с помощью PARSE_URL.

Наслаждаться

мой pathinfo отключен, а затем короткий способ извлечения строки расширения?

khizar ansari 10.08.2012 22:20

@khizaransari Вам стоит поискать другого хостинг-провайдера, тот, который у вас есть, глупый. На самом деле, я серьезно. Для отключения этой функции есть без причины. Скажи им это. В качестве обходного пути: function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); } Убедитесь, что файл имеет расширение, хотя он может делать что угодно, если вы передаете путь в качестве аргумента!

Luc 20.09.2012 21:29

У меня проблема с этим примером - он не работает с такими именами, как "............. doc", есть идеи, почему?

Bor 19.12.2013 12:33

мое представление о PHP по сравнению с python полностью изменилось теперь, когда я знаю об этой функции: O

Tommaso Barbugli 02.07.2014 14:22

@ e-satis, но он не работает в одном сценарии в моем приложении.Как иногда я получаю URL-адрес в следующем формате, www.domain.com/image.php?id=123&idlocation=987&number=01 для загрузки изображений, поскольку этот uRL не имеет имени изображения или расширения, с которым pathifo () отказывается дайте нам расширение изображения. ТАК что делать, пожалуйста !!! Помоги мне

Vikram Anand Bhushan 06.04.2015 15:37

Это действительно несправедливо, что я не потратил впустую столько, сколько другие люди здесь, а вместо этого нашел этот ответ и быстро решил свою проблему.

ted.strauss 14.04.2015 23:07

Это НЕ безопасное решение. Если кто-то загрузил на вашу конечную точку без использования браузера, он может подделать расширение. Например: pathinfo ('image.jpg.spoofed', PATHINFO_EXTENSION) возвращает 'spoofed' !! Он не проверяет фактическое тело файла, поскольку не принимает путь к файлу и не проверяет свой результат с помощью карты MimeType. Вы должны убедиться, что значение, которое вы получаете от этого, действительно является допустимым типом, запросив iana.org/assignments/media-types/media-types.txt или проверив свою собственную карту MimeType.

John Foley 23.04.2015 04:11
БУДЬ ОСТОРОЖЕН!!!!! ЭТО НЕ БЕЗОПАСНАЯ ФУНКЦИЯ !!! read other answers!
T.Todua 21.11.2016 14:31
Это очень медленный способ to do it, pathinfo does a lot more than what you're looking for and it's all discarded on return. I added another answer with some time measurements.
dkellner 07.04.2020 14:38

Ответ E-satis - это правильный способ определить расширение файла.

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

Вот упрощенный пример обработки изображения, загруженного пользователем:

// 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;
}

Это ЕДИНСТВЕННЫЙ правильный ответ. Я не понимаю, почему люди голосовали за других. Да, такой подход требует от разработчика больших усилий, но повышает производительность (хотя и немного, но дает). Пожалуйста, обратитесь к это.

Bhavik Shah 31.01.2014 11:43

@Bhavik: В некоторых случаях нам может понадобиться только расширение файла, они касаются проверки типа mime. Но на самом деле вопрос касается расширения файла, а не типа файла. Так что это НЕ лучший ответ на этот вопрос. (пока нет ответа)

Sasi varna kumar 23.10.2015 11:25

Если он не содержит пути, вы также можете использовать:

array_pop(explode('.', $fname))

Где $fname - это имя файла, например: my_picture.jpg. И результат будет: jpg

@ Почему здесь 3 голоса против? это дает правильный результат. Пожалуйста, объясни

railsbox 22.05.2014 10:23

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

user622327 15.07.2014 05:52

Это лучший способ, когда вам нужно настоящее расширение, а имя файла может содержать несколько., Например, загруженные пользователем фотографии в моем случае.

Rauli Rajande 21.07.2014 19:35

Это не удается, если имя файла не имеет расширения. Попробуйте передать «myfile», и он вернет «myfile». Правильное возвращаемое значение - это пустая строка в качестве расширения в этом случае использования.

pmont 05.12.2014 20:25

Это неправильно, потому что array_pop () выдаст уведомление, потому что он принимает указатель в качестве параметра.

jurchiks 31.07.2015 15:50

Также есть SplFileInfo:

$file = new SplFileInfo($path);
$ext  = $file->getExtension();

Часто можно написать лучший код, если передать такой объект вместо строки. Тогда ваш код более говорящий. Начиная с PHP 5.4 это однострочный:

$ext  = (new SplFileInfo($path))->getExtension();

Фантастический, его объекты полностью вниз :)

Christopher Chase 26.06.2013 19:12

Имейте в виду, что ->getExtension() доступен в SplFileInfo, начиная с PHP 5.3.6.

matthias 26.08.2014 16:02

@matthias: Имейте в виду, что SPL можно отключить в версиях PHP, предшествующих выпуску PHP 5.3.0. Если вы все еще не используете PHP 5.3, но 5.2 или ниже, этот ответ, скорее всего, не подходит для стабильного кода. В противном случае вы можете стабилизировать свой код, потребовав конкретную версию PHP, и в противном случае выйти из строя.

hakre 26.08.2014 16:24

@hakre Хотя вы правы, говоря, что «может быть отключено в версиях, предшествующих 5.3.0», расширение SPL, тем не менее, компилируется по умолчанию, начиная с PHP 5.0.0. Так что этот комментарий действительно имеет смысл для людей, вынужденных использовать PHP 5.2 или ниже и не желающих отказываться от использования определенных классов SPL.

matthias 26.08.2014 16:35

ага просто мертвый вариант пух :)

hakre 26.08.2014 17:02

$ext = pathinfo($file, PATHINFO_EXTENSION) или $ext = pathinfo($file)['extension'] лучше однострочники.

Iiridayn 16.03.2018 21:50

Иногда бывает полезно не использовать pathinfo($path, PATHINFO_EXTENSION). Например:

$path = '/path/to/file.tar.gz';

echo ltrim(strstr($path, '.'), '.'); // tar.gz
echo pathinfo($path, PATHINFO_EXTENSION); // gz

Также обратите внимание, что pathinfo не может обрабатывать некоторые символы, отличные от ASCII (обычно он просто подавляет их из вывода). В расширениях это обычно не проблема, но знать об этом нюансе не помешает.

@ e-satis: Согласно Википедия это два расширения: Файловые системы, подобные UNIX, используют другую модель без отдельных метаданных расширений. Точка - это просто еще один символ в главном имени файла, а имена файлов могут иметь несколько расширений, обычно представляющих вложенные преобразования, такие как files.tar.gz.

Alix Axel 02.11.2012 03:29

А если в названии товара есть точка? Пример: test.19-02-2014.jpeg

Mario Radomanana 26.03.2014 18:05

Это не удастся с /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.') работает как pathinfo, но без токенизации всего.

Ray Foss 09.09.2016 16:46

Использовать

str_replace('.', '', strrchr($file_name, '.'))

для быстрого поиска расширений (если вы точно знаете, что у вашего файла оно есть).

substr($path, strrpos($path, '.') + 1);

Это не удастся с /root/my.folder/my.css

Ray Foss 09.09.2016 16:44

Это должно работать правильно: substr ($ path, strrpos ($ path, '.') + 1); Примечание: этот метод работает быстрее, чем любые другие решения, указанные выше. Попробуйте выполнить тест, используя наш собственный скрипт.

Abbas 17.10.2016 08:04

1) Если вы используете (PHP 5> = 5.3.6) вы можете использовать SplFileInfo :: getExtension - получает расширение файла

Пример кода

<?php

$info = new SplFileInfo('test.png');
var_dump($info->getExtension());

$info = new SplFileInfo('test.tar.gz');
var_dump($info->getExtension());

?>

Это выведет

string(3) "png"
string(2) "gz"

2) Другой способ получить расширение, если вы используете (PHP 4> = 4.0.3, PHP 5), - это pathinfo

Пример кода

<?php

$ext = pathinfo('test.png', PATHINFO_EXTENSION);
var_dump($ext);

$ext = pathinfo('test.tar.gz', PATHINFO_EXTENSION);
var_dump($ext);

?>

Это выведет

string(3) "png"
string(2) "gz"

// Обновлено: удалили скобку

Это будет работать

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Субодх уже ответил на этот вопрос гораздо лучше еще в августе.

Nisse Engström 15.01.2015 15:18

Это уже предлагалось еще в 2008 году. Отправляйте ответ только в том случае, если у вас есть что-то уникальное и ценное. Избыточный контент только тратит время исследователей и раздувает страницы Stack Overflow.

mickmackusa 28.06.2020 07:03

Я обнаружил, что решения pathinfo() и SplFileInfo хорошо работают для стандартных файлов в локальной файловой системе, но вы можете столкнуться с трудностями, если работаете с удаленными файлами, поскольку URL-адреса для действительных изображений могут иметь # (идентификаторы фрагментов) и / или ?. (параметры запроса) в конце URL-адреса, который оба этих решения (неверно) будут рассматривать как часть расширения файла.

Я обнаружил, что это надежный способ использовать pathinfo() в URL-адресе после его первого анализа, чтобы убрать ненужный беспорядок после расширения файла:

$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()

Вот пример. Предположим, что $ filename - "example.txt",

$ext = substr($filename, strrpos($filename, '.', -1), strlen($filename));

Таким образом, $ ext будет ".txt".

Самый простой способ получить расширение файла в PHP - использовать встроенную функцию PHP 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

Быстрое исправление будет примерно таким.

// 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];

Почему бы просто не использовать встроенную функцию php для цели php.net/manual/en/function.pathinfo.php вместо использования длинного кода

Shahbaz 01.07.2015 08:40

Помимо точки зрения Шахбаза, вы также можете просто выполнить $file_ext = end(explode('.', $filename));, чтобы сделать все в этом ответе в одной строке вместо четырех.

tvanc 07.01.2016 05:49

@Amelia Что делать, если у вас есть .tar.gz. Это не сработает, поэтому, если вам нужно получить полное расширение, используйте, например, ltrim(strstr($filename, '.'), '.');, чтобы получить полное расширение, вместо того, чтобы некорректно, как gz.

Marin Sagovac 21.05.2016 23:00

Пример URL: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ

А) Не используйте предложенный небезопасный 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'

Б) Используйте 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'

БОНУС: Посмотреть все нативные примеры PHP

Этот ответ охватывает все, например. такой файл, как foo_folder/foo-file.jpg?1345838509, потерпит неудачу только с pathinfo, спасибо

user1299518 20.07.2015 09:46

Не совсем по теме, но это решило мою проблему!

Howie 24.11.2015 09:48

Ничего не забывай! parse_url - это URL, а pathinfo - путь к файлу.

Nabi K.A.Z. 09.06.2017 09:02

Что значит "забыть информацию о пути"? Вы используете его в решении!

Autumn Leonard 20.06.2017 17:12

@AutumnLeonard Он этого не делает, он просто показал разницу между pathinfo и parse_url.

user443346 29.08.2017 12:52

для тех, у кого есть проблемы с именами файлов, такими как Webp.net-resizeimage_% 288% 29.png? 1547034073, где у нас есть несколько точек, вы можете использовать функцию php end (), чтобы получить последний элемент массива, который включает формат файла

Artin Artin 01.07.2020 14:13

Вы можете получить все расширения файлов в определенной папке и выполнять операции с определенным расширением файла:

<?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);
?>

Вы также можете попробовать это:

 pathinfo(basename($_FILES["fileToUpload"]["name"]), PATHINFO_EXTENSION)

pathinfo - это массив. Можем проверить имя каталога, имя файла, расширение и т. Д .:

$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";

Если вы ищете скорость (например, в маршрутизаторе), вы, вероятно, не захотите токенизировать все. Многие другие ответы потерпят неудачу с /root/my.folder/my.css

ltrim(strrchr($PATH, '.'),'.');

Используйте substr($path, strrpos($path,'.')+1);. Это самый быстрый метод сравнения.

@ Курт Чжун уже ответил.

Проверим сравнительный результат здесь: https://eval.in/661574

Неа. Это не самый быстрый способ, и вы немного удивитесь, если вызовете его с именем файла без расширения.

dkellner 07.08.2020 02:42

Вы также можете попробовать это (работает на PHP 5. * и 7):

$info = new SplFileInfo('test.zip');
echo $info->getExtension(); // ----- Output -----> zip

Совет: возвращает пустую строку, если файл не имеет расширения.

Хотя «лучший способ» спорен, я считаю, что это лучший способ по нескольким причинам:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}
  1. Он работает с несколькими частями расширения, например tar.gz.
  2. Короткий и эффективный код
  3. Он работает как с именем файла, так и с полным путем

Собственно, я этого и искал.

<?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);

IMO, это лучший способ, если у вас есть имена файлов, такие как name.name.name.ext (уродливо, но иногда бывает):

$ext     = explode('.', $filename); // Explode the string
$my_ext  = end($ext); // Get the last entry of the array

echo $my_ext;

ltrim(strstr($file_url, '.'), '.')

this is the best way if you have filenames like name.name.name.ext (ugly, but it sometimes happens

Извините ... "Короткий вопрос; но НЕ короткий ответ"

Пример 1 для 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);

Пример 2 для 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);

Вывод примера 1:

Name: base.min
Extension: css

Результат примера 2:

Name: file.bak
Extension: php

использованная литература

  1. https://www.php.net/manual/en/function.pathinfo.php

  2. https://www.php.net/manual/en/function.realpath.php

  3. https://www.php.net/manual/en/function.parse-url.php

$ext = preg_replace('/^.*\.([^.]+)$/D', '', $fileName);

preg_replace, мы используем поиск и замену регулярных выражений. В функции preg_replace первый параметр - это шаблон для поиска, второй параметр $ 1 - это ссылка на то, что соответствует первому (. *), А третий параметр - имя файла.

Другой способ, мы также можем использовать strrpos, чтобы найти позицию последнего вхождения символа «.» В имени файла и увеличить эту позицию на 1, чтобы она взорвала строку из (.)

$ext = substr($fileName, strrpos($fileName, '.') + 1);

Сделай это быстрее.

Вызовы низкого уровня должны быть очень быстро, поэтому я подумал, что стоит провести некоторое исследование. Я пробовал несколько методов (с различной длиной строки, длиной расширения, несколькими запусками каждый), вот несколько разумных:

function method1($s) {return preg_replace("/.*\./","",$s);} // edge case problem
function method2($s) {preg_match("/\.([^\.]+)$/",$s,$a);return $a[1];}
function method3($s) {$n = strrpos($s,"."); if ($n===false) return "";return substr($s,$n+1);}
function method4($s) {$a = explode(".",$s);$n = count($a); if ($n==1) return "";return $a[$n-1];}
function method5($s) {return pathinfo($s, PATHINFO_EXTENSION);}

Полученные результаты были не очень удивительными. Плохой pathinfo (безусловно!) Самый медленный; даже с опцией PATHINFO_EXTENSION похоже, что он пытается все разобрать, а затем отбросить все ненужные части. С другой стороны, встроенная функция strrpos создана почти точно для этой работы, не требует обходных путей, поэтому неудивительно, что она работает намного лучше, чем другие кандидаты:

Original filename was: something.that.contains.dots.txt
Running 50 passes with 10000 iterations each
Minimum of measured times per pass:

    Method 1:   312.6 mike  (response: txt) // preg_replace
    Method 2:   472.9 mike  (response: txt) // preg_match
    Method 3:   167.8 mike  (response: txt) // strrpos
    Method 4:   340.3 mike  (response: txt) // explode
    Method 5:  2311.1 mike  (response: txt) // pathinfo  <--------- poor fella

ПРИМЕЧАНИЕ: у первого метода есть побочный эффект: он возвращает полное имя, когда нет расширения. Конечно, было бы бессмысленно измерять его с помощью дополнительных strpos, чтобы избежать такого поведения.

Заключение

Похоже, это Путь Самурая:

function fileExtension($s) {
    $n = strrpos($s,".");
    return ($n===false) ? "" : substr($s,$n+1);
}

Некоторые тестовые примеры

File name            fileExtension()
----------------------------------------
file                 ""
file.                ""
file.txt             "txt"
file.txt.bin         "bin"
file.txt.whatever    "whatever"
.htaccess            "htaccess"

(Последний вариант немного особенный; это может быть только расширение или пустое расширение с чистым именем ".htaccess", я не уверен, есть ли для этого правило. Так что я думаю, вы можете использовать оба , если вы знаете, что делаете.)

Большое спасибо за это. Всегда приятно найти эти хорошо исследованные новые ответы на старые вопросы. Экономит время, выясняя, какие методы могут быть устаревшими.

Leon Williams 23.01.2021 09:31

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

ungalcrys 02.02.2021 15:48

@ungalcrys в этом случае substr примет пустую часть, поэтому само расширение будет "", как и должно быть.

dkellner 02.02.2021 16:30

Я попробовал одно простое решение, которое может помочь кому-то другому получить только имя файла из URL-адреса, который имеет параметры

<?php

$path = "URL will be here";
echo basename(parse_url($path)['path']);

?>

Спасибо

Другие вопросы по теме