Як отримати розширення файлу в 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];

тощо.

Однак завжди є "найкращий спосіб", і він повинен бути на Stack Overflow.


15
Джерело запитань та відповідей: cowburn.info/2008/01/13/get-file-extension-compination
salathe

5
Ще один спосіб отримати extstrrchr($filename, '.');
verybadbug

Відповіді:


1776

Люди з інших мов сценаріїв завжди вважають, що їх краще, тому що вони мають вбудовану функцію для цього, а не PHP (я зараз дивлюся на Pythonistas :-)).

Насправді вона існує, але мало хто її знає. Знайомтесь pathinfo():

$ext = pathinfo($filename, PATHINFO_EXTENSION);

Це швидко і вбудовано. pathinfo()може надати вам іншу інформацію, наприклад, канонічний шлях, залежно від константи, яку ви переходите до неї.

Пам'ятайте, що якщо ви хочете мати змогу мати справу з символами, що не належать до ASCII, спочатку потрібно встановити локаль. EG:

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

Також зауважте, що це не враховує вміст файлу чи тип mime, ви отримуєте лише розширення. Але це те, про що ви просили.

Нарешті, зауважте, що це працює лише для шляху до файлу, а не до шляху ресурсів URL, який охоплюється за допомогою PARSE_URL.

Насолоджуйтесь


62
Я хотів би, щоб я міг проголосувати за це двічі. Я не можу сказати, скільки коду мені вдалося замінити за допомогою pathinfo
Марк Бік

8
Так і я. Тому я і поклав його сюди!
e-satis

7
Whaddaya знаю, виявляється, що найкращий спосіб.
Бен

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

12
моя ідея PHP порівняно з python повністю змінилася тепер, коли я знаю про цю функцію: O
Tommaso Barbugli

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'];
Салман A

1
Це навіть працює на цьому рівні (Twitter json): $ ext = pathinfo ($ result-> extension_entities-> media [0] -> video_info-> варіанти [1] -> url, PATHINFO_EXTENSION);
KJS

100

Приклад URL: http://example.com/myfolder/sympony.mp3?a=1&b=2#XYZ

A) Не використовуйте запропоновані небезпечні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) Використовуйте 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


3
Ця відповідь охоплює все, наприклад. файл на зразок foo_folder/foo-file.jpg?1345838509не вдасться pathinfo

1
Не зовсім тематично, але це, безумовно, вирішило мою проблему!
Howie

7
Не забувайте нічого! parse_urlпризначений для URL-адреси та pathinfoпризначений для файлу.
Nabi KAZ

1
Що ви маєте на увазі "забути інформацію про шлях"? Ви використовуєте його в розчині!
Осінній Леонард

1
@AutumnLeonard Він цього не робить, він просто показав відмінності між pathinfo та parse_url.

59

Є також SplFileInfo:

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

Часто ви можете написати кращий код, якщо передаєте такий об’єкт навколо замість рядка. Ваш код тоді більше говорить. Оскільки PHP 5.4, це однолінійний:

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

Фантастичний, його об'єкти аж донизу :)
Крістофер Чейз

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.
Маттіас

так, просто мертвий варіант пуху :)
hakre

23

Відповідь E-satis - це правильний спосіб визначення розширення файлу.

Крім того, замість того, щоб покладатися на розширення файлів, ви можете використовувати інформацію про файл, щоб визначити тип файлу 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. Але власне питання стосується розширення файлу, а не типу файлу. Тож це НЕ найкраща відповідь на це питання. (поки відповідь)
Сасі варна кумар

для цього перемикача потрібна додаткова дужка
rsb2097

16

Поки він не містить шлях, ви також можете використовувати:

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

Де $fnameце ім'я файлу, наприклад: my_picture.jpg. І результат був би таким:jpg


@ Чому у цього 3 нижніх записів? це дає належний результат. Поясніть, будь ласка,
railsbox

Це не помиляється, це просто не найкращий спосіб зробити це. Захищений за трохи балансу.

Це найкращий спосіб, коли потрібне реальне розширення та ім’я файлу може бути декількома. У ньому, як і завантажені користувачем фотографії в моєму випадку.
Rauli Rajande

2
Це не вдається, якщо ім'я файлу не має розширення. Спробуйте передати "myfile", і він поверне "myfile". Правильне значення повернення - порожній рядок як розширення в цьому випадку використання.
пмонт

Це неправильно в тому, що array_pop () видасть повідомлення, оскільки він вказує вказівник як свій параметр.
jurchiks

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), є інформація

Приклад коду

<?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: вилучено дужку


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-satis: Відповідно до Вікіпедії, це два розширення: Файлові системи, схожі на UNIX, використовують іншу модель без метаданих розширеного розширення. Символ крапки - це лише інший символ у головному імені файлу, і назви файлів можуть мати декілька розширень, зазвичай представляючи вкладені перетворення, наприклад files.tar.gz .
Алікс Аксель

1
І якщо ми маємо крапку у назві продукту? Напр .:test.19-02-2014.jpeg
Маріо Радоманана

Це не вдасться, коли /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.')працює як pathinfo, але без токенізації всього.
Рей Фосс

8

Найпростіший спосіб отримати розширення файлів у PHP - це використання вбудованої функції PHP для введення інформації .

$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

8

Ви можете також спробувати це (це працює на PHP 5. * і 7):

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

Порада: він повертає порожній рядок, якщо файл не має розширення


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

Чому б не просто використовувати вбудовану функцію php з метою php.net/manual/en/function.pathinfo.php замість того, щоб використовувати довгий код
Шахбаз

1
Крім точки зору Шахбаза, ви також можете просто зробити $file_ext = end(explode('.', $filename));все, що є у цій відповіді, в один рядок замість чотирьох.
tvanc

@Amelia Що робити, якщо у вас є .tar.gz. Це не спрацює, тому якщо вам потрібно отримати повне використання розширення, наприклад, ltrim(strstr($filename, '.'), '.');щоб отримати повне розширення, а не неправильно як gz.
Марін Саговач

6

Ось приклад. Припустимо, ім’я $ $ - "example.txt",

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

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


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
ltrim(strstr($file_url, '.'), '.')

це найкращий спосіб, якщо у вас є назви файлів на зразок name.name.name.ext (некрасиво, але іноді це трапляється



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);. Це найшвидший метод з усіх порівнянь.

@Kurt Zhong вже відповів.

Перевіримо порівняльний результат тут: 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

ПРИМІТКА. Перший метод має побічний ефект: він повертає всю назву, коли немає розширення. Безумовно, не було б сенсу вимірювати це додатковими стрипами, щоб уникнути такої поведінки.

Висновок

Це виглядає як Шлях Самураїв:

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

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;

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, '.'))

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.