ChatGPT解决这个技术问题 Extra ChatGPT

如何在 PHP 中获取文件的扩展名?

这是一个您可以在网络上随处阅读的问题,并提供各种答案:

$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。

获取分机的另一种方法是 strrchr($filename, '.');
strrpos 是正确的方法(请参阅我的答案),但它需要为无扩展情况添加。

S
Sayed Mohd Ali

来自其他脚本语言的人总是认为他们的更好,因为他们有一个内置函数可以做到这一点,而不是 PHP(我现在正在看 Pythonistas :-))。

事实上,它确实存在,但很少有人知道。认识pathinfo()

$ext = pathinfo($filename, PATHINFO_EXTENSION);

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

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

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

另外,请注意,这不考虑文件内容或 mime 类型,您只会获得扩展名。但这是你要求的。

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

享受


我的路径信息被禁用然后提取扩展字符串的捷径?
@khizaransari您应该寻找另一个托管服务提供商,您得到的那个很愚蠢。真的,我是认真的。 没有任何理由禁用此功能。告诉他们。解决方法:function get_ext($fname){ return substr($fname, strrpos($fname, ".") + 1); } 请确保文件有扩展名,当您将路径作为参数传递时,它可能会做任何事情!
我对这个例子有疑问 - 它不适用于“........doc”之类的名称,有什么想法吗?
与 python 相比,我对 PHP 的看法完全改变了,因为我知道了这个函数:O
这不是一个安全的解决方案。如果有人在不使用浏览器的情况下上传到您的端点,他们可能会欺骗扩展程序。例如: pathinfo('image.jpg.spoofed',PATHINFO_EXTENSION) 返回 'spoofed' !!它不检查实际的文件主体,因为它不采用文件路径,并且不使用 MimeType Map 验证其结果。您应该通过查询 iana.org/assignments/media-types/media-types.txt 或检查您自己的 MimeType Map 来确保从中接收到的值实际上是有效类型。
T
T.Todua

pathinfo()

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

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

自 PHP 5.5 -> echo pathinfo('/foo/bar/baz.bill')['extension'];
这甚至适用于这个级别(Twitter json): $ext = pathinfo($result->extended_entities->media[0]->video_info->variants[1]->url, PATHINFO_EXTENSION);
d
dipenparmar12

示例网址: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'

奖励:查看 all native PHP examples


这个答案涵盖了所有内容,例如。像 foo_folder/foo-file.jpg?1345838509 这样的文件只会因为 pathinfo 而失败,thanx
不完全是主题,但它确实解决了我的问题!
什么都不要忘记! parse_url 用于 URL,pathinfo 用于文件路径。
你是什么意思“忘记路径信息”?您在解决方案中使用它!
@AutumnLeonard他没有,他只是展示了pathinfo和parse_url之间的区别。
P
Peter Mortensen

还有SplFileInfo

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

如果传递这样的对象而不是字符串,通常可以编写更好的代码。你的代码更有说服力。从 PHP 5.4 开始,这是一个单行代码:

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

太棒了,它的对象一直向下:)
请注意 ->getExtension() 自 PHP 5.3.6 起在 SplFileInfo 中可用。
@matthias:请注意,在 PHP 5.3.0 之前的 PHP 版本中可以禁用 SPL。如果您仍然没有运行 PHP 5.3 而是 5.2 或更低版本,那么这个答案很可能不适合稳定的代码。否则,您可以通过要求特定的 PHP 版本来稳定您的代码,否则就会退出。
@hakre 虽然您说“可以在 5.3.0 之前的版本中禁用”是正确的,但从 PHP 5.0.0 开始,SPL 扩展仍然默认编译。因此,对于被迫使用 PHP 5.2 或更低版本并且不想使用特定 SPL 类辞职的人来说,此评论确实有意义。
$ext = pathinfo($file, PATHINFO_EXTENSION)$ext = pathinfo($file)['extension'] 是更好的单行。
T
Top-Master

做的更快!

换句话说,如果您只使用文件名,请停止使用 pathinfo。

我的意思是,如果你有一个完整的路径名,pathinfo 是有意义的,因为它比仅仅查找点更聪明:路径可以包含点,而文件名本身可能没有。所以在这种情况下,考虑像 d:/some.thing/myfile 这样的输入字符串,pathinfo 和其他配备齐全的方法是一个不错的选择。

但是如果你只有一个文件名,没有路径,那么让系统工作得比它需要的多得多是毫无意义的。这可以为您提供 10 倍的速度提升。

这是一个快速的速度测试:

/*   387 ns */ function method1($s) {return preg_replace("/.*\./","",$s);} // edge case problem
/*   769 ns */ function method2($s) {preg_match("/\.([^\.]+)$/",$s,$a);return $a[1];}
/*    67 ns */ function method3($s) {$n = strrpos($s,"."); if($n===false) return "";return substr($s,$n+1);}
/*   175 ns */ function method4($s) {$a = explode(".",$s);$n = count($a); if($n==1) return "";return $a[$n-1];}
/*   731 ns */ function method5($s) {return pathinfo($s, PATHINFO_EXTENSION);}
/*   732 ns */ function method6($s) {return (new SplFileInfo($s))->getExtension();}

//  All measured on Linux; it will be vastly different on Windows

这些纳秒值在每个系统上显然会有所不同,但它们给出了关于比例的清晰画面。 SplFileInfopathinfo 是很棒的家伙,但是对于这种工作来说,唤醒他们根本不值得。出于同样的原因,explode() 比正则表达式快得多。非常简单的工具往往胜过更复杂的工具。

结论

这似乎是武士之道:

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

请记住,这仅适用于简单的文件名。如果您涉及路径,请坚持使用 pathinfo 或单独处理目录名。


非常感谢这一点。在旧问题上找到那些经过充分研究的新答案总是很高兴。节省时间找出哪些技术可能已经过时。
strrpos 方法可能需要再次检查这种情况,没有扩展名“文件名”。
@ungalcrys 在这种情况下, substr 将占用一个空白部分,因此扩展本身将是“”,就像它应该的那样。
@dkellner 是否还想对 $info = new SplFileInfo('test.png');$info->getExtension(); 进行基准测试?
@TimoHuovinen 我用于此基准测试的服务器现在得到完全不同的结果。可能也有一个 php 更新,但可以肯定它是一个更强大的硬件。无论如何,虽然 phpinfo 现在与 method1 大致相同,但 splFileInfo 一样慢,甚至慢一点。我想我会更新图表。
P
Peter Mortensen

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

这是唯一正确的答案。我不明白为什么人们投票支持其他人。是的,这种方法需要开发人员付出更多的努力,但它提高了性能(虽然很少,但确实如此)。请参阅this
@Bhavik:在某些情况下,我们可能只需要文件扩展名,它们是关于 mime 类型检查的。但实际问题是关于文件扩展名,而不是文件类型。所以这不是这个问题的最佳答案。 (还有答案)
文件名甚至不意味着该文件存在,所以任何依赖于内容的东西一开始都是错误的。然后,即使有一个实际文件,打开它也比只知道名称要慢得多,而且您甚至无法确定您是否有权访问该文件本身。更不用说锁定和其他潜在问题了。所以不行。这不是最好的答案,实际上远非如此。
P
Peter Mortensen

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

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

其中 $fname 是文件的名称,例如:my_picture.jpg。结果将是:jpg


@为什么这有 3 个反对票?它给出了正确的结果。请解释
这没有错,只是不是最好的方法。赞成有点平衡。
这是最好的方法,当您需要真正的扩展名和文件名时,其中可能包含多个 .,例如用户上传的照片。
如果文件名没有扩展名,则会失败。尝试传入“myfile”,它将返回“myfile”。在这个用例中,正确的返回值是一个空字符串作为扩展名。
这是错误的,因为 array_pop() 会抛出一个通知,因为它需要一个指针作为它的参数。
n
nils

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"

// 编辑:删除了一个括号


P
Peter Mortensen

有时不使用 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:根据 Wikipedia,它们是两个扩展:类 UNIX 文件系统使用不同的模型,没有隔离的扩展元数据。点字符只是主文件名中的另一个字符,文件名可以有多个扩展名,通常表示嵌套转换,例如 files.tar.gz
如果我们在产品名称中有点?例如:test.19-02-2014.jpeg
这将失败,因为 /root/my.folder/my.css ltrim(strrchr($PATH, '.'),'.') 像 pathinfo 一样工作,但没有对所有内容进行标记。
A
Ali Han

抱歉...“简短的问题;但不是简短的答案”

PATH 示例 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);

URL 示例 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

参考

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


P
Peter Mortensen

在 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

P
Peter Mortensen

你也可以试试这个(它适用于 PHP 5.* 和 7):

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

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


P
Peter Mortensen

这是一个例子。假设 $filename 是“example.txt”,

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

所以 $ext 将是“.txt”。


P
Peter Mortensen

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

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

这将因 /root/my.folder/my.css 而失败
这必须正常工作: substr($path, strrpos($path,'.')+1);注意:此方法比上述任何其他解决方案都快。使用我们自己的脚本尝试基准测试。
它非常快,但是对于根本没有扩展名的文件有一个严重的问题。在这种情况下,它会删除第一个字符。请参阅上面的解决方案(Ctrl+F 并输入 samurai);几乎一样,只是有这么小的差别。所以是的,这个方法确实很酷而且超级快,但是你应该注意边缘情况。
P
Peter Mortensen

快速修复将是这样的。

// 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 的观点之外,您还可以只执行 $file_ext = end(explode('.', $filename)); 以在一行而不是四行中完成此答案中的所有内容。
@Amelia 如果你有 .tar.gz 怎么办。它不起作用,因此如果您需要完全扩展使用,例如 ltrim(strstr($filename, '.'), '.'); 来获得完全扩展,而不是不正确地使用 gz
P
Peter Mortensen

你也可以试试这个:

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

T
Tommy89

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;

J
Jonathan Ellis

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

我发现这是在第一次解析 URL 以去除文件扩展名后不必要的混乱之后在 URL 上使用 pathinfo() 的可靠方法:

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

P
Peter Mortensen

使用 substr($path, strrpos($path,'.')+1);。这是所有比较中最快的方法。

@Kurt Zhong 已经回答了。

让我们在这里检查比较结果:https://eval.in/661574


没有。它不是最快的,如果您使用没有扩展名的文件名调用它,它会给您带来一点惊喜。
S
Salman Zafar
ltrim(strstr($file_url, '.'), '.')

如果您有像 name.name.name.ext 这样的文件名,这是最好的方法(丑陋,但有时会发生


对我来说这没有意义。它只删除第一个之前的所有内容。 (点)并在之后返回所有内容。这意味着,如果您有类似的内容: www.indexpage.com/videos/phpExtensions.mp4?v/345 您提出的方法将返回 indexpage.com/videos/phpExtensions.mp4?v/345 并且这不是文件扩展名。还是我错过了什么?
D
Deepika Patel

这将起作用

$ext = pathinfo($filename, PATHINFO_EXTENSION);

早在 8 月,Subodh 就已经更好地回答了这个问题。
早在 2008 年就已经提出了这一建议。请仅在您有独特且有价值的东西要给出时才发布答案。冗余内容只会浪费研究人员的时间,并且会使 Stack Overflow 页面膨胀。
P
Peter Mortensen

您可以获取特定文件夹中的所有文件扩展名并使用特定文件扩展名进行操作:

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

S
Sai Kiran Sangam

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

preg_replace 方法我们使用正则表达式搜索和替换。在 preg_replace 函数中,第一个参数是搜索的模式,第二个参数 $1 是对第一个 (.*) 匹配的任何内容的引用,第三个参数是文件名。

另一种方式,我们也可以使用 strrpos 来查找最后一次出现 '.' 的位置。在文件名中并将该位置增加 1,以便它将从 (.)

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


R
Ray Foss

如果您正在寻找速度(例如在路由器中),您可能不想标记所有内容。许多其他答案将因/root/my.folder/my.css而失败

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

D
Dan Bray

尽管“最佳方式”值得商榷,但我相信这是最好的方式,原因如下:

function getExt($path)
{
    $basename = basename($path);
    return substr($basename, strlen(explode('.', $basename)[0]) + 1);
}

它适用于扩展的多个部分,例如 tar.gz 短而高效的代码 它适用于文件名和完整路径


F
Fred

其实,我就是在找那个。

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

A
Ashok Chandrapal

我尝试了一种简单的解决方案,它可能有助于其他人从具有获取参数的 URL 中获取文件名

<?php

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

?>

谢谢


R
RafaSashi

在一行中:

pathinfo(parse_url($url,PHP_URL_PATH),PATHINFO_EXTENSION);

A
AlexB

利用

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

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