basename

(PHP 4, PHP 5, PHP 7, PHP 8)

basename返回路径中的文件名部分

说明

basename ( string $path , string $suffix = ? ) : string

给出一个包含有指向一个文件的全路径的字符串,本函数返回基本的文件名。

Note:

basename() 纯粹基于输入字符串操作, 它不会受实际文件系统和类似 ".." 的路径格式影响。

Caution

basename() 是本地化的, 所以如果要正确处理多字节字符的路径, 需要用 setlocale() 正确设置匹配的 locale。

参数

path

一个路径。

在 Windows 中,斜线(/)和反斜线(\)都可以用作目录分隔符。在其它环境下是斜线(/)。

suffix

如果文件名是以 suffix 结束的,那这一部分也会被去掉。

返回值

Returns the base name of the given path. 返回 path 的基本的文件名。

范例

Example #1 basename() 例子

<?php
echo "1) ".basename("/etc/sudoers.d"".d").PHP_EOL;
echo 
"2) ".basename("/etc/sudoers.d").PHP_EOL;
echo 
"3) ".basename("/etc/passwd").PHP_EOL;
echo 
"4) ".basename("/etc/").PHP_EOL;
echo 
"5) ".basename(".").PHP_EOL;
echo 
"6) ".basename("/");
?>

以上例程会输出:

1) sudoers
2) sudoers.d
3) passwd
4) etc
5) .
6) 

参见

User Contributed Notes

stocki dot r at gmail dot com 10-Apr-2019 11:02
Additional note to Anonymous's mb_basename() solution: get rid of trailing slashes/backslashes!

<?php
function mb_basename($path) {
    if (
preg_match('@^.*[\\\\/]([^\\\\/]+)([\\\\/]+)?$@s', $path, $matches)) {
        return
$matches[1];
    } else if (
preg_match('@^([^\\\\/]+)([\\\\/]+)?$@s', $path, $matches)) {
        return
$matches[1];
    }
    return
'';
}

echo
mb_basename("/etc//"); # "etc"
?>
wibgates dot kenneth at gmail dot com 11-Sep-2017 01:49
the best way to get the filename from url is here
<?php
     
// url : http://php.net/manual/add-note.php

      
defined('baseUrlFileName') or define('baseUrlFileName',
      
explode('.',explode('/',$_SERVER['PHP_SELF'])[3])[0]);

     echo
baseUrlFileName ; // result 1

?>

Result 1 :
    add-note
Anonymous 20-Jul-2017 05:04
It's a shame, that for a 20 years of development we don't have mb_basename() yet!

// works both in windows and unix
function mb_basename($path) {
    if (preg_match('@^.*[\\\\/]([^\\\\/]+)$@s', $path, $matches)) {
        return $matches[1];
    } else if (preg_match('@^([^\\\\/]+)$@s', $path, $matches)) {
        return $matches[1];
    }
    return '';
}
frank1982 31-Mar-2017 10:22
Try Long Path Tool as it can remove any problems that you might have.
Anonymous 10-Mar-2017 08:05
There is a problem reading non-Latin characters in the file name if the locale is not configured correctly.
For example: instead of the name ?ФЫВА-1234.doc?, is displayed ?-1234.doc?.
Solution: rawurldecode(basename($full_name)).
gandung at ppp dot cylab dot cmu dot edu 20-Feb-2017 11:49
My opinion is, remove the $suffix first, and then apply splitting the core basename ( PHP 4 ):

/*
 * From [email protected]:
 *
 * PHP 4: $suffix is removed first, and then the core basename is applied.
 * PHP 5: $suffix is removed after applying the core basename.
 *
 * (c) Paulus Gandung Prakosa ([email protected])
 */
if ( !function_exists('php4_backward_compat_basename') )
{
        function php4_backward_compat_basename($path, $suffix = '')
        {
                if ( $suffix !== '' ) {
                        $fixed_path = substr($path, 0, strlen($path) - strlen($suffix));
                        $fixed_basename = explode('/', $fixed_path);
                }

                return ( isset($fixed_basename) ? array_pop($fixed_basename) : array_pop(explode('/', $path)) );
        }
}
Anonymous 15-Dec-2014 02:30
As already pointed out above, if a query string contains a '/' character, basename will not handle it well. But it can come really handy when you want to pass a url with query string to a funtion that copies/downloads the file using basename as local filename, by attaching  an extra query to the end of the url:

<?php
  $url
= 'http://example.com/url?with=query_string';
 
basename($url); // url?with=query_string
 
$url = $url . '&filename_for_basename=/desired_filename.ext';
 
basename($url); // desired_filename.ext
?>

Note: you can use the filename from the HTTP header (if present) to get the file with it's original filename.
poop at poop dot com 22-Nov-2014 12:42
@ lcvalentine at gmail dot com
>This is much simpler:
>$ext = strrchr( $filename, '.' );

Even though yours is shorter, you can also do:

$ext = end(explode(".", basename($file
lcvalentine at gmail dot com 21-Nov-2014 04:32
@softontherocks at gmail dot com
> If you want to get the extension of a file, I posted a function in
> http://softontherocks.blogspot.com/2013/07/obtener-la-extension-de-un-fichero-con.html
>
> The function is:
>
> function getExtension($file) {
>   $pos = strrpos($file, '.');
>   return substr($file, $pos+1);
> }

This is much simpler:
$ext = strrchr( $filename, '.' );
softontherocks at gmail dot com 31-Oct-2014 06:38
If you want to get the extension of a file, I posted a function in http://softontherocks.blogspot.com/2013/07/obtener-la-extension-de-un-fichero-con.html

The function is:

 function getExtension($file) {
  $pos = strrpos($file, '.');
  return substr($file, $pos+1);
 }
Muhammad El-Saeed muhammad at elsaeed dot info 19-Apr-2013 04:58
to get the base url of my website

function url(){
    $base_url = isset($_SERVER['HTTPS']) && strtolower($_SERVER['HTTPS']) !== 'off' ? 'https' : 'http';
    $base_url .= '://'. $_SERVER['HTTP_HOST'];
    $base_url .= str_replace(basename($_SERVER['SCRIPT_NAME']), '', $_SERVER['SCRIPT_NAME']); 
    return $base_url;
}
swedish boy 12-Oct-2009 03:43
Here is a quick way of fetching only the filename (without extension) regardless of what suffix the file has.

<?php

// your file
$file = 'image.jpg';

$info = pathinfo($file);
$file_name basename($file,'.'.$info['extension']);

echo
$file_name; // outputs 'image'

?>
hello at haroonahmad dot co dot uk 18-Sep-2008 08:13
I got a blank output from this code

$cur_dir = basename(dirname($_SERVER[PHP_SELF]))

suggested earlier by a friend here.

So anybody who wants to get the current directory path can use another technique that I use as

//suppose you're using this in pageitself.php page

$current_dir=dirname(realpath("pageitself.php"));

I hope it helps.
zandor_zz at yahoo dot it 08-Sep-2008 01:34
It might be useful to have a version of the function basename working with arrays too.

<?php
function a_basename( $file, $exts )
{
   
$onlyfilename = end( explode( "/", $file ) );

    if(
is_string( $exts ) )
    {
        if (
strpos( $onlyfilename, $exts, 0 ) !== false )
       
$onlyfilename = str_replace( $exts, "", $onlyfilename );
    }
    else if (
is_array( $exts ) )
    {
       
// works with PHP version <= 5.x.x
       
foreach( $exts as $KEY => $ext )
        {
           
$onlyfilename = str_replace( $ext, "", $onlyfilename );
        }
    }

    return
$onlyfilename ;
}
?>
(remove) dot nasretdinov at (remove) dot gmail dot com 27-Aug-2008 08:20
There is only one variant that works in my case for my Russian UTF-8 letters:

<?php
function mb_basename($file)
{
    return
end(explode('/',$file));
}
><

It is intented for UNIX servers
pai dot ravi at yahoo dot com 15-Aug-2008 08:44
once you have extracted the basename from the full path and want to separate the extension from the file name, the following function will do it efficiently:

<?php
function splitFilename($filename)
{
   
$pos = strrpos($filename, '.');
    if (
$pos === false)
    {
// dot is not found in the filename
       
return array($filename, ''); // no extension
   
}
    else
    {
       
$basename = substr($filename, 0, $pos);
       
$extension = substr($filename, $pos+1);
        return array(
$basename, $extension);
    }
}
?>
adrian at foeder dot de 20-Dec-2007 12:33
On windows systems, filenames are case-insensitive. If you have to make sure the right case is used when you port your application to an unix system, you may use a combination of the following:

<?php
//assume the real filename is mytest.JPG:

$name_i_have = "mytest.jpg";
$realfilename = basename(realpath($name_i_have));
?>

basename itself does not check the filesystem for the given file, it does, so it seems, only string-manipulation.
With realpath() you can "extend" this functionality.
stephane dot fidanza at gmail dot com 11-Apr-2007 04:33
Support of the $suffix parameter has changed between PHP4 and PHP5:
in PHP4, $suffix is removed first, and then the core basename is applied.
conversely, in PHP5, $suffix is removed AFTER applying core basename.

Example:
<?php
  $file
= "path/to/file.xml#xpointer(/Texture)";
  echo
basename($file, ".xml#xpointer(/Texture)");
?>

Result in PHP4: file
Result in PHP5: Texture)
thoughts at highermind dot org 30-Jan-2007 05:45
Basename without query string:

<?php
$filename   
= array_shift(explode('?', basename($url_path)));
?>
lazy lester 17-Feb-2006 04:19
If your path has a query string appended, and if the query string contains a "/" character, then the suggestions for extracting the filename offered below don't work.

For instance if the path is like this:
http://www.ex.com/getdat.php?dep=n/a&title=boss

Then both the php basename() function, and also
the $_SERVER[QUERY_STRING] variables get confused.

In such a case, use:

<php
$path_with_query="http://www.ex.com/getdat.php?dep=n/a&title=boss";
$path=explode("?",$path_with_query);
$filename=basename($path[0]);
$query=$path[1];
?>
15-Nov-2005 04:57
icewinds exmaple wouldn't work, the query part would contain the second char of the filename, not the query part of the url.
<?
$file = "path/file.php?var=foo";
$file = explode("?", basename($file));
$query = $file[1];
$file = $file[0];
?>

That works better.
icewind 02-Nov-2005 12:44
Because of filename() gets "file.php?var=foo", i use explode in addition to basename like here:

$file = "path/file.php?var=foo";
$file = explode("?", basename($file));
$file = $file[0];
$query = $file[1];

Now $file only contains "file.php" and $query contains the query-string (in this case "var=foo").
www.turigeza.com 24-Oct-2005 12:47
simple but not said in the above examples

echo basename('somewhere.com/filename.php?id=2', '.php');
will output
filename.php?id=2

which is not the filename in case you expect!
crash at subsection dot org dot uk 22-Sep-2005 12:38
A simple way to return the current directory:
$cur_dir = basename(dirname($_SERVER[PHP_SELF]))

since basename always treats a path as a path to a file, e.g.

/var/www/site/foo/ indicates /var/www/site as the path to file
foo
amitabh at NOSPAM dot saysnetsoft dot com 14-Jul-2005 01:55
The previous example posted by "pvollma" didn't work out for me, so I modified it slightly:
<?php
function GetFileName($file_name)
{
       
$newfile = basename($file_name);
        if (
strpos($newfile,'\\') !== false)
        {
               
$tmp = preg_split("[\\\]",$newfile);
               
$newfile = $tmp[count($tmp) - 1];
                return(
$newfile);
        }
        else
        {
                return(
$file_name);
        }
}
?>
pvollma at pcvsoftware dot net 13-Jul-2005 11:43
There is a real problem when using this function on *nix servers, since it does not handle Windows paths (using the \ as a separator). Why would this be an issue on *nix servers? What if you need to handle file uploads from MS IE? In fact, the manual section "Handling file uploads" uses basename() in an example, but this will NOT extract the file name from a Windows path such as C:\My Documents\My Name\filename.ext. After much frustrated coding, here is how I handled it (might not be the best, but it works):

<?php
$newfile
= basename($filen);
if (
strpos($newfile,'\\') !== false) {
 
$tmp = preg_split("[\\\]",$newfile);
 
$newfile = $tmp[count($tmp) - 1];
}
?>

$newfile will now contain only the file name and extension, even if the POSTed file name included a full Windows path.
KOmaSHOOTER at gmx dot de 30-Jan-2005 06:18
if you want the name of the parent directory
<?php
$_parenDir_path
= join(array_slice(split( "/" ,dirname($_SERVER['PHP_SELF'])),0,-1),"/").'/'; // returns the full path to the parent dir
$_parenDir basename ($_parenDir_path,"/"); // returns only the name of the parent dir
// or
$_parenDir2 = array_pop(array_slice(split( "/" ,dirname($_SERVER['PHP_SELF'])),0,-1)); // returns also only the name of the parent dir
echo('$_parenDir_path  = '.$_parenDir_path.'<br>');
echo(
'$_parenDir  = '.$_parenDir.'<br>');
echo(
'$_parenDir2  = '.$_parenDir2.'<br>');
?>
KOmaSHOOTER at gmx dot de 29-Jan-2005 04:24
If you want the current path where youre file is and not the full path then use this :)

<?php
echo('dir = '.basename (dirname($_SERVER['PHP_SELF']),"/"));   
// retuns the name of current used directory
?>

Example:

www dir: domain.com/temp/2005/january/t1.php

<?php
echo('dirname <br>'.dirname($_SERVER['PHP_SELF']).'<br><br>');   
// returns: /temp/2005/january
?>

<?php
echo('file = '.basename ($PHP_SELF,".php"));   
// returns: t1
?>

if you combine these two you get this
<?php
echo('dir = '.basename (dirname($_SERVER['PHP_SELF']),"/"));   
// returns: january
?>

And for the full path use this
<?php
echo(' PHP_SELF <br>'.$_SERVER['PHP_SELF'].'<br><br>');
// returns: /temp/2005/january/t1.php   
?>
KOmaSHOOTER at gmx dot de 28-Nov-2003 02:33
Exmaple for exploding ;) the filename to an array

<?php
echo(basename ($PHP_SELF)."<br>");  // returnes filename.php
$file = basename ($PHP_SELF);
$file = explode(".",$file);
print_r($file);    // returnes Array ( [0] => filename [1] => php )
echo("<br>");
$filename = basename(strval($file[0]),$file[1]);
echo(
$filename."<br>");  // returnes  filename
echo(basename ($PHP_SELF,".php")."<br>");  // returnes  filename
echo("<br>");
echo(
"<br>");
//show_source(basename ($PHP_SELF,".php").".php")
show_source($file[0].".".$file[1])
?>
daijoubu_NOSP at M_videotron dot ca 15-Oct-2003 10:22
An faster alternative to:

<?php
array_pop
(explode('.', $fpath));
?>

would be:

<?php
substr
($fpath, strrpos($fpath, '.')); // returns the dot
?>

If you don't want the dot, simply adds 1 to the position

<?php
substr
($fpath, strrpos($fpath, '.') + 1); // returns the ext only
?>