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

691

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

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

и т.п.

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

  • 12
    Источник вопроса и ответа: cowburn.info/2008/01/13/get-file-extension-comparison
  • 3
    Еще один способ получить ext - это strrchr($filename, '.');
Теги:
file-extension

23 ответа

1571
Лучший ответ

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

На самом деле, оно существует, но мало кто это знает. Познакомьтесь с pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

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

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

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

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

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

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

  • 52
    Я хотел бы проголосовать за это дважды. Я не могу сказать вам, сколько кода я смог заменить, используя pathinfo
  • 6
    Я тоже. Вот почему я положил это здесь!
Показать ещё 13 комментариев
149

pathinfo()

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

echo $path_info['extension']; // "bill"
  • 2
    Это "лучший способ"
  • 13
    Начиная с PHP 5.5 -> echo pathinfo('/foo/bar/baz.bill')['extension'];
Показать ещё 1 комментарий
81

URL-адрес примера: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ

Забудьте уязвимого PATHINFO !

$x = pathinfo($url);
$x['dirname']   ? 'http://example.com/myfolder'
$x['basename']  ? 'sympony.mp3?a=1&b=2#XYZ'         // <------- BAD !!
$x['extension'] ? 'mp3?a=1&b=2#XYZ'                 // <------- BAD !!
$x['filename']  ? 'sympony'

Используйте более безопасный PARSE_URL:

$x = parse_url($url);
$x['scheme']  ? 'http'
$x['host']    ? 'example.com'
$x['path']    ? '/myfolder/sympony.mp3'
$x['query']   ? 'aa=1&bb=2'
$x['fragment']? 'XYZ'             

Примечание: хештеги недоступны на стороне сервера, только если они добавлены вручную.


Для всех собственных примеров PHP см.: Получить полный URL в PHP

  • 3
    Этот ответ охватывает все, например. такой файл, как foo_folder/foo-file.jpg?1345838509 потерпит неудачу с помощью только pathinfo , спасибо
  • 0
    Не совсем по теме, но это точно решило мою проблему!
Показать ещё 4 комментария
53

Существует также SplFileInfo:

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

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

$ext  = (new SplFileInfo($path))->getExtension();
  • 11
    Приятно видеть, что мой код используется. :)
  • 2
    @salathe: Да, хороший код :) Спасибо за все это.
Показать ещё 6 комментариев
19

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

В качестве альтернативы вместо использования расширения файлов вы можете использовать fileinfo (http://us2.php.net/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;
}
  • 1
    Это единственный правильный ответ. Я не понимаю, почему люди проголосовали за других. Да, этот подход требует больше усилий от разработчика, но он повышает производительность (хотя и мало, но это так). Пожалуйста, обратитесь это .
  • 2
    @Bhavik: В некоторых случаях нам может понадобиться только расширение файла, они о проверке MIME-типа. Но фактический вопрос касается расширения файла, а не типа файла. Так что это НЕ лучший ответ на этот вопрос. (пока ответ)
Показать ещё 1 комментарий
12

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"

//EDIT: удалена скобка

10

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

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

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

  • 0
    @ Почему у этого есть 3 отрицательных голоса? это дает правильный результат. Пожалуйста, объясни
  • 0
    Это не так, это просто не лучший способ сделать это. Проголосовал за немного баланса.
Показать ещё 3 комментария
9

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

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

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

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

  • 0
    +1 но это серая зона. Является ли tar.gz расширением или .gz?
  • 6
    @ e-sat: Согласно Википедии, они являются двумя расширениями: UNIX-подобные файловые системы используют другую модель без разделенных метаданных расширения. Точечный символ - это просто еще один символ в главном имени файла, и имена файлов могут иметь несколько расширений, обычно представляющих вложенные преобразования, такие как files.tar.gz .
Показать ещё 2 комментария
7

Самый простой способ получить расширение файла в php - использовать встроенную функцию php pathinfo.

$file_ext = pathinfo('your_file_name_here', PATHINFO_EXTENSION);
echo ($file_ext); // the out should be extension of file eg:-png, gif, html
5

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

    //exploding the file based on . 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];
  • 0
    Почему бы просто не использовать встроенную функцию php для php.net/manual/en/function.pathinfo.php вместо длинного кода
  • 1
    Помимо точки зрения Шахбаза, вы также можете просто сделать $file_ext = end(explode('.', $filename)); сделать все в этом ответе в одной строке вместо четырех.
Показать ещё 1 комментарий
5
substr($path, strrpos($path, '.') + 1);
  • 0
    Это не удастся с /root/my.folder/my.css
  • 0
    Это должно работать правильно: substr ($ path, strrpos ($ path, '.') + 1); Примечание: этот метод быстрее, чем любые другие решения выше. Попробуйте эталонный тест, используя наш собственный скрипт.
4

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

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

tip: он возвращает пустую строку, если файл не имеет расширения
наслаждайтесь этим;)

4

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

Вот пример, предположим, что $filename является "example.txt"

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

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

3

Я обнаружил, что решения 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()
3

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

$ext = pathinfo($filename, PATHINFO_EXTENSION);
  • 0
    На это уже гораздо лучше ответил Субод еще в августе.
2

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

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

2

вы также можете попробовать следующее:

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

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

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

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

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

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

<?php
    $files=glob("abc/*.*");//abc is 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 perticular extenstion type
        if($extension=='html'){
            //do operation
        }
    endfor;
    print_r($ext);
?>
0

На самом деле, я искал это.

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

Используйте

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

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню