PHP,获取不带文件扩展名的文件名


205

我有这个PHP代码:

function ShowFileExtension($filepath)
{
    preg_match('/[^?]*/', $filepath, $matches);
    $string = $matches[0];

    $pattern = preg_split('/\./', $string, -1, PREG_SPLIT_OFFSET_CAPTURE);

    if(count($pattern) > 1)
    {
        $filenamepart = $pattern[count($pattern)-1][0];
        preg_match('/[^?]*/', $filenamepart, $matches);
        return strtolower($matches[0]);
    }
}

如果我有一个名为的文件my.zip,则此函数返回.zip

我想做相反的事情,我希望函数my不带扩展名就返回。

该文件只是变量中的字符串。


Answers:


397

不需要所有这些。pathinfo(),它为您提供了路径的所有组件。

手册中的示例:

$path_parts = pathinfo('/www/htdocs/index.html');

echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['extension'], "\n";
echo $path_parts['filename'], "\n"; // filename is only since PHP 5.2.0

代码输出:

/www/htdocs
index.html
html
index

或者,您只能获得某些部分,例如:

echo pathinfo('/www/htdocs/index.html', PATHINFO_EXTENSION); // outputs html

3
为什么这被否决?答案是绝对正确的。pathinfo对字符串进行操作,因此文件实际上是否在服务器上都没有关系。
戈登

13
不幸的是,他们把“ basename”改名为“ basename”,因为它返回带有扩展名的完整文件名,而不是基本名称。
奥斯卡

1
@Oscar是该术语最广泛理解的含义basename。别误会。
nawfal

1
这非常有用,尤其是当您不需要知道文件扩展名来提取它时。
Vahid Amiri

这是一个非常优雅的解决方案。荣誉 应该将其标记为正确答案。
Native Coder

199

作为替代pathinfo(),您可以使用

PHP手册中的示例

$path = "/home/httpd/html/index.php";
$file = basename($path);         // $file is set to "index.php"
$file = basename($path, ".php"); // $file is set to "index"

您必须知道扩展名才能提前将其删除。

但是,由于您的问题表明您需要获取扩展名基本名称,因此,我将Pekka的答案投票为最有用的答案,因为它将为您提供有关单个路径和文件的任何信息功能。


1
如果我不知道文件扩展名怎么办..如果路径是动态的,可以输入任何类型的文件扩展名!那是什么??
user889030'2013/

@ user889030,那么您将拥有与OP不同的方案,并且不使用basename,但是pathinfo页面上的else 如下所示。
哥顿

72

https://php.net/manual/zh/function.pathinfo.php

pathinfo($path, PATHINFO_FILENAME);

简单的功能测试:https//ideone.com/POhIDC


这将返回带有扩展名的文件名
user966939 2014年

2
@ user966939 Mhh,不扩展名是basename;-)
yckart 2014年

好吧,无论哪种方式,他都在寻求一个没有扩展的解决方案。;)
user966939 2014年

2
@ user966939,Dude完全没有扩展名。是的PATHINFO_FILENAME,不是PATHINFO_EXTENSION ....
Pacerier's

20
谁决定在filename不延长的同时basename一定要有一些虐待狂的倾向……
Mark

12

另一种方法是使用正则表达式。

$fileName = basename($filePath);
$fileNameNoExtension = preg_replace("/\.[^.]+$/", "", $fileName);

这将从最后一个期间删除,.直到字符串末尾。


我喜欢这个答案,非常简单,可以在您不知道扩展名的情况下使用。
2014年

比使用explode更好,并且仅在文件名中使用句点的情况下才捕获最后一个句点部分
Kiwizoom 2015年

7
,情况要糟得多。停止让别人烦恼。
Pacerier 2015年

谢谢,上面的评论把它钉牢了。不必知道扩展名,这将更加有用。
James Taylor

1
@ caiosm1005,攻击面立即增加,因为很难对正则表达式引擎的内部进行推理。例如,在上面的代码中,如果有一些输入$fileName可能导致引擎在指数(或更差的)时间内运行,这并不奇怪。假设我们已经完成了对这个特定regex引擎内部结构的剖析,并在理论上证明了它对于可能的每个值$fileName都具有鲁棒性,那么该代码仍然不会随便移植到具有regex引擎另一种实现方式的另一个平台上。
Pacerier

12

如果扩展名未知,请使用此解决方案

 pathinfo('D:/dir1/dir2/fname', PATHINFO_FILENAME); // return "fname"
 pathinfo('D:/dir1/dir2/fname.php', PATHINFO_FILENAME); // return "fname"
 pathinfo('D:/dir1/dir2/fname.jpg', PATHINFO_FILENAME); // return "fname"

 pathinfo('D:/dir1/dir2/fname.jpg', PATHINFO_DIRNAME) . '/' . pathinfo('D:/dir1/dir2/fname.jpg', PATHINFO_FILENAME); // return "D:/dir1/dir2/fname"

PHP MAN函数pathinfo


请提供与相似的php手册页pathinfo。这将有助于OP ShowFileExtension改进方法,并为尝试找到此答案的任何人提供额外的阅读材料。同样一点描述也不会误入歧途...
Michael Coxon 2015年

1
我已经用相同的解决方案回答了这个问题,比您早了2年;)
yckart

@yckart是的,但这确实在答案中提供了多个示例。您的网站可以链接到ideone.com,但该网站可能会离线。
亚当·埃尔索达尼

7

如果您知道扩展名,则@Gordon basename可以正常工作,如果不知道,则可以使用explode:

$filename = end(explode(".", $file));

1
请使用我的答案下方的评论功能将评论直接发送给我。最合适的功能是pathinfo,这就是为什么我basename只提供了替代功能。无需pathinfo使用regex或explode
Gordon

4
@fire,您的更新没有任何意义。end(explode(".", $file));给您扩展名,而不是文件名。
Pacerier 2015年

7

以上几乎所有解决方案都显示了从变量$ path获取文件名

下面的代码片段将获取当前执行的文件名称,不带扩展名

echo pathinfo(basename($_SERVER['SCRIPT_NAME']), PATHINFO_FILENAME);

说明

$ _SERVER ['SCRIPT_NAME']包含当前脚本的路径。



4

@fire如果文件名使用点,您可能会得到错误的输出。我会使用@Gordon方法,但也要获取扩展名,因此basename函数适用于所有扩展名,如下所示:

$path = "/home/httpd/html/index.php";
$ext = pathinfo($path, PATHINFO_EXTENSION);

$file = basename($path, ".".$ext); // $file is set to "index"

4

就我而言,我在下面使用。我不在乎它的范围。:D我认为它将为您提供帮助

$exploded_filepath = explode(".", $filepath_or_URL);
$extension = end($exploded_filepath);
echo basename($filepath_or_URL, ".".$extension ); //will print out the the name without extension.

顺便说一句:您有错字$extenion
托马斯·凯基森

2

你可以写这个

$filename = current(explode(".", $file));

如果以前没有使用过,这些将返回数组的当前元素。


您好,请在降级之前先检查一下。我已经在代码中多次使用了它,这是正常的。通过使用此功能,您可以仅获取文件名(如果文件名是“ xyz.jpg”)。它可能不适用于其中包含完整路径的文件名。
Jitendra Pawar

如果文件名中包含多个点,例如“ some.interesting.image.jpg”,这也将无法正常工作
ganzpopp

2

echo pathinfo(__FILE__)['filename']; // since php 5.2

好。但是,如果我在把上面的代码b.php,我执行a.phprequire('b.php')。然后输出将如何b而不是a
Rohan Khude


1

如果您不知道拥有哪个扩展名,则可以尝试以下操作:

$ext = strtolower(substr('yourFileName.ext', strrpos('yourFileName.ext', '.') + 1));
echo basename('yourFileName.ext','.'.$ext); // output: "youFileName" only

千方百计地工作:

image.jpg // output: "image"
filename.image.png // output: "filename.image"
index.php // output: "index"

1

您的答案是在php中隐藏文件扩展名的理想解决方案。

<?php
    $path = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    echo basename($path, ".php");
?>

1

当扩展包含多个部分时,现有解决方案将失败。下面的函数可用于多个部分,完整路径或仅文件名:

function removeExt($path)
{
    $basename = basename($path);
    return strpos($basename, '.') === false ? $path : substr($path, 0, - strlen($basename) + strlen(explode('.', $basename)[0]));
}

echo removeExt('https://example.com/file.php');
// https://example.com/file
echo removeExt('https://example.com/file.tar.gz');
// https://example.com/file
echo removeExt('file.tar.gz');
// file
echo removeExt('file');
// file

0

这仅在1行中返回不带任何扩展名的文件名:

$path = "/etc/sudoers.php";    
print array_shift(explode(".", basename($path)));
// will print "sudoers"

$file = "file_name.php";    
print array_shift(explode(".", basename($file)));
// will print "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.