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

723

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

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

и т.п.

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

е-удовлетворяться
источник
15
Источник вопроса и ответа: cowburn.info/2008/01/13/get-file-extension-comparison
salathe
5
Еще один способ получить strrchr($filename, '.');
добро

Ответы:

1776

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

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

$ext = pathinfo($filename, PATHINFO_EXTENSION);

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

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

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

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

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

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

е-удовлетворяться
источник
62
Я хотел бы проголосовать за это дважды. Я не могу сказать вам, сколько кода я смог заменить, используя pathinfo
Марк
8
Я тоже. Вот почему я положил это здесь!
е-сат
7
Как знать, оказывается, есть лучший способ.
Бен
19
@khizaransari Вы должны искать другого хостинг-провайдера, тот, который вы получили, глуп. На самом деле, я имею в виду это. Нет никаких причин отключать эту функцию. Скажи им это. В качестве обходного пути: function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }убедитесь, что файл имеет расширение, однако он может делать что угодно, когда вы передаете путь в качестве аргумента!
Люк
12
мое представление о PHP по сравнению с python полностью изменилось, теперь, когда я знаю об этой функции: O
Томмазо Барбугли
166

pathinfo()

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

echo $path_info['extension']; // "bill"
Адам Райт
источник
14
Начиная с PHP 5.5 ->echo pathinfo('/foo/bar/baz.bill')['extension'];
Salman A
1
Это даже работает на этом уровне (Twitter json): $ ext = pathinfo ($ result-> extended_entities-> media [0] -> video_info-> варианты [1] -> URL, PATHINFO_EXTENSION);
KJS
101

Пример 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

T.Todua
источник
3
Этот ответ охватывает все, например. файл как с foo_folder/foo-file.jpg?1345838509треском провалится с просто pathinfo, спасибо
1
Не совсем по теме, но это точно решило мою проблему!
Хауи
7
Не забывайте ничего! parse_urlдля URL и pathinfoдля пути к файлу.
Наби КАЗ
1
Что вы имеете в виду "забыть путь информации"? Вы используете это в решении!
Осень Леонард
1
@AutumnLeonard Нет, он просто показал различия между pathinfo и parse_url.
59

Также есть SplFileInfo:

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

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

$ext  = (new SplFileInfo($path))->getExtension();
hakre
источник
Фантастика, все объекты спущены :)
Кристофер Чейз
2
Обратите внимание, что ->getExtension()доступно в SplFileInfo начиная с PHP 5.3.6.
Матиас
1
@matthias: имейте в виду, что SPL можно отключить в версиях PHP, предшествующих версии PHP 5.3.0. Если вы все еще не используете PHP 5.3, но 5.2 или ниже, этот ответ, скорее всего, не подходит для стабильного кода. В противном случае вы можете стабилизировать свой код, требуя конкретной версии PHP, и в противном случае выручите.
Хакре
@hakre Хотя вы правы, говоря, что «его можно отключить в версиях, предшествующих 5.3.0», расширение SPL тем не менее компилируется по умолчанию в PHP 5.0.0. Так что этот комментарий действительно имеет смысл для людей, которые вынуждены использовать PHP 5.2 или ниже и не хотят уходить в отставку, используя определенные классы SPL.
Маттиас
да, просто мертвая версия пух :)
хакре
23

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

В качестве альтернативы, вместо того, чтобы полагаться на расширение файлов, вы можете использовать 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;
}
Toxygene
источник
1
Это единственный правильный ответ. Я не понимаю, почему люди проголосовали за других. Да, этот подход требует больше усилий от разработчика, но он повышает производительность (хотя и мало, но это так). Пожалуйста, обратитесь это .
Бхавик Шах
2
@Bhavik: В некоторых случаях нам может понадобиться только расширение файла, они о проверке MIME-типа. Но фактический вопрос касается расширения файла, а не типа файла. Так что это НЕ лучший ответ на этот вопрос. (пока ответ)
Саси Варна Кумар
этот переключатель требует дополнительных скобок
rsb2097
16

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

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

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

анонимное
источник
@ Почему у этого есть 3 отрицательных голоса? это дает правильный результат. Пожалуйста, объясните
railsbox
Это не так, просто это не лучший способ сделать это. Проголосовал за немного баланса.
Это лучший способ, когда вам нужно реальное расширение и имя файла может содержать несколько символов. Например, загруженные пользователем фотографии в моем случае.
Раули Раджанде
2
Это не удастся, если имя файла не имеет расширения. Попробуйте передать «myfile», и он вернет «myfile». Правильное возвращаемое значение - пустая строка как расширение в этом случае использования.
Пмонт
Это неправильно в том, что array_pop () выдаст уведомление, потому что в качестве параметра он принимает указатель.
Юрсикс
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"

// РЕДАКТИРОВАТЬ: убрал скобку

Subodh Ghulaxe
источник
12

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

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

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

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

Аликс Аксель
источник
6
@ e-sat: Согласно Википедии, они являются двумя расширениями: UNIX-подобные файловые системы используют другую модель без разделенных метаданных расширения. Точечный символ - это просто еще один символ в главном имени файла, и имена файлов могут иметь несколько расширений, обычно представляющих вложенные преобразования, такие как files.tar.gz .
Аликс Аксель
1
А если у нас есть точка в названии продукта? Пример:test.19-02-2014.jpeg
Марио Радоманана
Это не удастся, так как /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.')работает как pathinfo, но без токенизации всего.
Рэй Фосс
8

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

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

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

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

pooya_sabramooz
источник
7

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

Пример 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

Али
источник
6

Быстрое исправление будет что-то вроде этого.

// 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];
версия 2
источник
Почему бы просто не использовать встроенную функцию php для целей php.net/manual/en/function.pathinfo.php вместо длинного кода
Шахбаз
1
Помимо точки зрения Шахбаза, вы также можете сделать $file_ext = end(explode('.', $filename));все, что в этом ответе, в одной строке вместо четырех.
tvanc
@ Амелия Что если у тебя есть .tar.gz. Это не будет работать, поэтому, если вам нужно получить полное расширение, используйте его, например, ltrim(strstr($filename, '.'), '.');чтобы получить полное расширение вместо неправильно gz.
Марин Саговац
6

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

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

Так что $ ext будет ".txt".

GI Joe
источник
6

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";
Аршид К.В.
источник
5
substr($path, strrpos($path, '.') + 1);
Курт Чжун
источник
1
Это не удастся с /root/my.folder/my.css
Рэй Фосс
1
Это должно работать правильно: substr ($ path, strrpos ($ path, '.') + 1); Примечание: этот метод быстрее, чем любые другие решения выше. Попробуйте бенчмарк, используя наш собственный скрипт.
Аббас
4

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

 pathinfo(basename($_FILES["fileToUpload"]["name"]), PATHINFO_EXTENSION)
улыбка 22121
источник
4
ltrim(strstr($file_url, '.'), '.')

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

Анджани Барнвал
источник
3

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

$ext = pathinfo($filename, PATHINFO_EXTENSION);
Дипика Патель
источник
На это уже гораздо лучше ответил Субод еще в августе.
Ниссе Энгстрем
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

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

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

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

Аббас
источник
2

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

<?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);
?>
Самир Кармачарья
источник
2

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

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

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(безусловно!) Самый медленный (похоже, он пытается разобрать все это, а затем отбросить все ненужные части) - и method3()(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);
}
dkellner
источник
1

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

ltrim(strrchr($PATH, '.'),'.');
Рэй Фосс
источник
1

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

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

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

$ext     = explode('.', $filename); // Explode the string
$ext_len = count($ext) - 1; // Count the array -1 (because count() starts from 1)
$my_ext  = $ext[$ext_len]; // Get the last entry of the array

echo $my_ext;
Tommy89
источник
1

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

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

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

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

Саи Киран Сангам
источник
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);
Фред
источник
-1

использование

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

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

AlexB
источник