如何在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];

等等

但是,始终存在“最佳方法”,并且应该在堆栈溢出中使用。



5
获取ext的strrchr($filename, '.');

Answers:


1776

来自其他脚本语言的人们总是认为自己的语言更好,因为他们具有内置功能而不是PHP(我现在正在研究Pythonistas :-)。

实际上,它确实存在,但是很少有人知道。相约pathinfo()

$ext = pathinfo($filename, PATHINFO_EXTENSION);

这是快速且内置的。pathinfo()可以根据传递给它的常量为您提供其他信息,例如规范路径。

请记住,如果您希望能够处理非ASCII字符,则需要先设置语言环境。例如:

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

另外,请注意,这并未考虑文件内容或mime类型,您只能获得扩展名。但这就是您要的。

最后,请注意,这仅适用于文件路径,不适用于使用PARSE_URL覆盖的URL资源路径。

请享用


62
我希望我可以投票两次。我无法告诉您我已经可以使用pathinfo替换多少代码
Mark Biek

8
我也是。这就是为什么我把它放在这里!
e-satis

7
Whaddaya知道,事实证明是最好的方法。

19
@khizaransari您应该寻找另一家托管服务提供商,这很愚蠢。真的,是真的。没有任何理由来禁用该功能。告诉他们。解决方法:function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); }尽管请确保文件具有扩展名,但在将路径作为参数传递时它可能会执行任何操作!
卢克

12
现在,我对这个函数的了解让我对PHP与python的比较的想法彻底改变了:O
Tommaso Barbugli 2014年

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-> variants [1]-> url,PATHINFO_EXTENSION);
KJS

100

范例网址: 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?1345838509pathinfo,thanx 会惨败

1
并非完全是主题,但确实可以解决我的问题!
Howie

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

太棒了,其目标一直向下:)
Christopher Chase

2
请注意,->getExtension()自PHP 5.3.6起该功能在SplFileInfo中可用。
matthias

1
@matthias:请注意,可以在PHP 5.3.0发行版之前的PHP版本中禁用SPL。如果您仍未运行PHP 5.3,但仍未运行5.2或更低版本,则此答案很可能不适合稳定的代码。否则,您可以通过要求特定的PHP版本来稳定代码,否则请采取紧急措施。
hakre 2014年

@hakre正确地说“可以在5.3.0之前的版本中禁用”,但是默认情况下,PHP 5.0.0起默认编译了SPL扩展名。因此,对于被迫使用PHP 5.2或更低版本并且不想使用特定SPL类退出的人们,此注释确实有意义。
matthias 2014年

是的,只是死版本绒毛:)
hakre 2014年

23

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

1
这是唯一正确的答案。我不明白为什么人们会投票赞成别人。是的,这种方法需要开发人员付出更多的努力,但可以提高性能(虽然效果不大,但确实可以)。请参考 这个
Bhavik Shah 2014年

2
@Bhavik:在某些情况下,我们可能仅需要文件扩展名,它们涉及mime类型检查。但是实际的问题是关于文件扩展名,而不是文件类型。因此,这不是此问题的最佳答案。(尚未回答)
Sasi varna kumar 2015年

此开关需要额外的括号
rsb2097 '16

16

只要它不包含路径,您也可以使用:

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

$fname文件的名称在哪里,例如:my_picture.jpg。结果将是:jpg


@为什么这有3票?它给出适当的结果。请解释
railsbox

没错,这不是最佳方法。争取获得一些平衡。

这是最好的方法,当您需要真实的扩展名且文件名中可能包含多个。时,例如用户上传的照片。
2014年

2
如果文件名没有扩展名,则失败。尝试传递“ myfile”,它将返回“ myfile”。在此用例中,正确的返回值是一个空字符串作为扩展名。
2014年

这是错误的,因为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),则获取扩展的另一种方法是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"

//编辑:删除括号


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:根据Wikipedia的介绍,它们是两个扩展:类UNIX的文件系统使用不同的模型,而没有分离的扩展元数据。点字符只是主文件名中的另一个字符,文件名可以具有多个扩展名,通常表示嵌套的转换,例如files.tar.gz
Alix Axel 2012年

1
如果我们在产品名称中加点号?例如:test.19-02-2014.jpeg
Mario Radomanana 2014年

这将失败,因为/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

8

您也可以尝试这样做(它在PHP 5. *和7上有效):

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

提示:如果文件没有扩展名,它将返回一个空字符串


7

对不起...“简短的问题;但不是简短的答案”

路径示例1

$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 = "//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/zh/function.pathinfo.php

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

  3. https://www.php.net/manual/zh/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.net/manual/en/function.pathinfo.php而不是使用长代码的原因
Shahbaz

1
除了Shahbaz的观点之外,您还可以$file_ext = end(explode('.', $filename));单行而不是四行地完成此答案中的所有操作。
tvanc

@Amelia如果有的话.tar.gz。它将无法正常工作,因此,如果您需要使用扩展名,请使用,例如,不正确ltrim(strstr($filename, '.'), '.');地使用gz
Marin Sagovac '16

6

这是一个例子。假设$ filename是“ 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而失败
Ray Foss

1
这必须正常工作:substr($ path,strrpos($ path,'。')+ 1); 注意:此方法比以上任何其他解决方案都快。使用我们自己的脚本尝试基准测试。
阿巴斯

4

您也可以尝试以下操作:

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



3

我发现pathinfo()SplFileInfo解决方案适用于本地文件系统上的标准文件,但是如果您正在使用远程文件,则可能会遇到麻烦,因为有效图像的URL可能具有#(片段标识符)和/或?(查询参数) URL的末尾,这两种解决方案都将(不正确地)将其视为文件扩展名的一部分。

我发现这是pathinfo()在首先解析URL以消除文件扩展名后不必要的混乱之后在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);。这是所有比较中最快的方法。

@钟ur已经回答了。

让我们在这里检查比较结果: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, '.'))

快速扩展名检索(如果您确定您的文件名有一个)。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.