pathinfo()
(PHP 4 >= 4.0.3, PHP 5, PHP 7)
返回文件路径的信息
说明
pathinfo(string $path[,int $options= PATHINFO_DIRNAME | PATHINFO_BASENAME | PATHINFO_EXTENSION | PATHINFO_FILENAME]): mixed
pathinfo()返回一个关联数组包含有path的信息。返回关联数组还是字符串取决于$options。
参数
- $path
- 要解析的路径。 
- $options
- 如果指定了,将会返回指定元素;它们包括: - PATHINFO_DIRNAME,- PATHINFO_BASENAME和- PATHINFO_EXTENSION或- PATHINFO_FILENAME。- 如果没有指定$options默认是返回全部的单元。 
返回值
如果没有传入$options,将会返回包括以下单元的数组array:dirname,basename和extension(如果有),以及filename。
Note:If the$pathdoes not have an extension,noextensionelement will be returned(以下第二个案例)。
If$optionsis present, returns astringcontaining the requested element.
更新日志
| 版本 | 说明 | 
|---|---|
| 5.2.0 | 添加了常量 PATHINFO_FILENAME。 | 
范例
Example #1pathinfo()例子
<?php
$path_parts = pathinfo('/www/htdocs/inc/lib.inc.php');
echo $path_parts['dirname'], "\n";
echo $path_parts['basename'], "\n";
echo $path_parts['extension'], "\n";
echo $path_parts['filename'], "\n"; // since PHP 5.2.0
?>
以上例程会输出:
/www/htdocs/inc lib.inc.php php lib.inc
Example #2pathinfo()example showing difference between null and no extension
<?php
$path_parts = pathinfo('/path/emptyextension.');
var_dump($path_parts['extension']);
$path_parts = pathinfo('/path/noextension');
var_dump($path_parts['extension']);
?>
以上例程的输出类似于:
string(0) "" Notice: Undefined index: extension in test.php on line 6 NULL
注释
Note:有关取得当前路径信息的说明,请阅读预定义变量一节。
Note:pathinfo()is locale aware, so for it to parse a path containing multibyte characters correctly, the matching locale must be set using thesetlocale()function.
参见
- dirname()返回路径中的目录部分
- basename()返回路径中的文件名部分
- parse_url()解析 URL,返回其组成部分
- realpath()返回规范化的绝对路径名
Simple example of pathinfo and array destructuring in PHP 7:
<?php
[ 'basename' => $basename, 'dirname' => $dirname ] = pathinfo('/www/htdocs/inc/lib.inc.php');
var_dump($basename, $dirname);
// result:
// string(11) "lib.inc.php"
// string(15) "/www/htdocs/inc"
?>
Note:
pathinfo() is locale aware, so for it to parse a path containing multibyte characters correctly, the matching locale must be set using the setlocale() function. 
Reality:
var_dump(pathinfo('中国人2016.xls'));
exit();
array(4) { 'dirname' => string(1) "." 'basename' => string(8) "2016.xls" 'extension' => string(3) "xls" 'filename' => string(4) "2016" } 
Expect(Solve):
setlocale(LC_ALL, 'zh_CN.UTF-8');
var_dump(pathinfo('中国人2016.xls'));
exit();
array(4) { 'dirname' => string(1) "." 'basename' => string(17) "中国人2016.xls" 'extension' => string(3) "xls" 'filename' => string(13) "中国人2016" }Use this function in place of pathinfo to make it work with UTF-8 encoded file names too
<?php
function mb_pathinfo($filepath) {
  preg_match('%^(.*?)[\\\\/]*(([^/\\\\]*?)(\.([^\.\\\\/]+?)|))[\\\\/\.]*$%im',$filepath,$m);
  if($m[1]) $ret['dirname']=$m[1];
  if($m[2]) $ret['basename']=$m[2];
  if($m[5]) $ret['extension']=$m[5];
  if($m[3]) $ret['filename']=$m[3];
  return $ret;
}
?>
Checked with version 5.5.12:
It works fine with filenames with utf-8 characters, pathinfo will strip them away:
<?php
print_r(pathinfo("/mnt/files/飛兒樂團光茫.mp3"));
?>
.. will display:
Array
(
  [dirname] => /mnt/files
  [basename] => 飛兒樂團光茫.mp3
  [extension] => mp3
  [filename] => 飛兒樂團光茫
)//pathinfo function example
<?php
//passing single argument
echo "<pre>";
print_r(pathinfo("/home/ramki/ramki.pdf"));
echo "</pre>";
//passing two agruments
$path=array(PATHINFO_DIRNAME,PATHINFO_BASENAME,PATHINFO_EXTENSION,PATHINFO_FILENAME);
foreach ($path as $value)
echo "<pre>".pathinfo("/home/ramki/ramki.pdf",$value)."</pre>";
?>
//output
/*
Array
(
  [dirname] => /home/ramki
  [basename] => ramki.pdf
  [extension] => pdf
  [filename] => ramki
)
/home/ramki
ramki.pdf
pdf
ramki
*/If a file has more than one 'file extension' (seperated by periods), the last one will be returned.
For example:
<?php
$pathinfo = pathinfo('/dir/test.tar.gz');
echo 'Extension: '.$pathinfo['extension'];
?>
will produce:
Extension: gz
and not tar.gzat example from "qutechie at gmail dot com" you can only replace function 'strpos' with 'strrpos'. (strrpos — Find position of last occurrence of a char in a string)
It's simple. For example:
<?php
function filePath($filePath)
{
 $fileParts = pathinfo($filePath);
 if(!isset($fileParts['filename']))
 {$fileParts['filename'] = substr($fileParts['basename'], 0, strrpos($fileParts['basename'], '.'));}
 
 return $fileParts;
}
 
$filePath = filePath('/www/htdocs/index.html');
print_r($filePath);
?>
Output will be:
Array
(
  [dirname] => /www/htdocs
  [basename] => index.html
  [extension] => html
  [filename] => index
)Here is a simple function that gets the extension of a file. Simply using PATHINFO_EXTENSION will yield incorrect results if the path contains a query string with dots in the parameter names (for eg. &x.1=2&y.1=5), so this function eliminates the query string first and subsequently runs PATHINFO_EXTENSION on the clean path/url.
<?php
function extension($path) {
 $qpos = strpos($path, "?");
 if ($qpos!==false) $path = substr($path, 0, $qpos);
 
 $extension = pathinfo($path, PATHINFO_EXTENSION);
 return $extension;
}
?>
Note that in PHP 4 (if you're stuck using it), pathinfo only provides dirname, basename, and extension, but not filename. This function will not split a file's stem and extension for you.
If you have filename with utf-8 characters, pathinfo will strip them away:
print_r(pathinfo("/mnt/files/飛兒樂團光茫.mp3"));
 .. will display:
Array
(
  [dirname] => /mnt/files
  [basename] => .mp3
  [extension] => mp3
  [filename] => 
)about the path, there are one thing you should note : On Windows, both slash (/) and backslash (\) are used as directory separator character. In other environments, it is the forward slash (/). (this explain is from basename() function part https://www.php.net/manual/en/function.basename.php) example: <?php $path = "http://www.test.com/a\b\c\filename.pdf"; echo pathinfo($pdfUrl, PATHINFO_BASENAME); //get basename //output //on window: result is filename.pdf //on Linux: result is a\b\c\filename.pdf (that is may not your expect) //so in order to get same result in different system. i will do below first. $path = str_replace($path, '\\', '/'); //convert '\' to '/' ?>
<?php // suppose we are using a path like = www/myfiles/script.js const FILE = "www/myfiles/script.js"; // print file name echo pathinfo(FILE,PATHINFO_FILENAME)."\n"; // print file extension echo pathinfo(FILE,PATHINFO_EXTENSION)."\n"; // print file Full name echo pathinfo(FILE,PATHINFO_BASENAME)."\n"; // print file directory name echo pathinfo(FILE,PATHINFO_DIRNAME)."\n";
any type of url parse_url can handle this will get the extension of
pathinfo(parse_url('URL GOES HERE',PHP_URL_PATH),PATHINFO_EXTENSION)A little compat for < 5.2
<?php
function pathinfo_filename($file) { //file.name.ext, returns file.name
  if (defined('PATHINFO_FILENAME')) return pathinfo($file,PATHINFO_FILENAME);
  if (strstr($file, '.')) return substr($file,0,strrpos($file,'.'));
}
?>
if you call pathinfo with a filename in url-style (example.php?with=parameter), make sure you remove the given parameters before, otherwise they will be returned as part of the extension. extension => php?with=parameter
Note that this function seems to just perform string operations, and will work even on a non-existent path, e.g.
<?php
print_r(pathinfo('/no/where/file.txt'));
?>
which will output:
Array
(
  [dirname] => /no/where
  [basename] => file.txt
  [extension] => txt
  [filename] => file
)If you want only the file extension, use this: <?php $extension = substr(strrchr($filename, "."), 1); ?> This is many times faster than using pathinfo() and getting the value from array.
Here's a neat wee function to grab the relative path to root (especially useful if you're using mock-directories to pass variables into scripts with mod_rewrite). The function simply iterates through every occurence of "/" within the REQUEST_URI environment variable, appending "../" to the output for every instance:
<?php
function path_to_root($path) {
  $pathinfo = pathinfo($path);
  
  $deep = substr_count($pathinfo[dirname], "/");
  
  $path_to_root = "./";
  
  for($i = 1; $i <= $deep; $i++) {
  
    $path_to_root .= "../";
    
  }
  
  return $path_to_root;
}
path_to_root($REQUEST_URI);
?>
Here is an enhanced version of pathinfo() that interprets multi-part extensions like tar.gz as one file extension:
<?php
function pathinfo_enhanced($file_path) {
 $core_path_info = pathinfo($file_path);
 $filename = $core_path_info['filename'];
 if (isset($core_path_info['extension'])) {
  $extension = $core_path_info['extension'];
 } else {
  $extension = '';
 }
 $extension_parts = array();
 while (!empty($extension)) {
  array_unshift($extension_parts, $extension);
  $remaining_path_info = pathinfo($filename);
  $filename = $remaining_path_info['filename'];
  if (isset($remaining_path_info['extension'])) {
   $extension = $remaining_path_info['extension'];
  } else {
   $extension = '';
  }
 }
 $revised_path_info = array(
  'filename' => $filename,
  'extension' => implode('.', $extension_parts),
 );
 return array_merge($core_path_info, $revised_path_info);
}
// === EXAMPLES ===
// Directory; two extensions
$path = '/www/htdocs/inc/file.tar.gz';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// Directory; one extension
$path = '/www/htdocs/inc/file.tgz';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// Directory; no extension
$path = '/www/htdocs/inc/lib';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// No directory; one extension
$path = 'test.php';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// No directory; dot file
$path = '.example';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";
// Directory only
$path = '/www/htdocs/inc/';
$info = pathinfo_enhanced($path);
echo "$path\n";
print_r($info);
echo "\n";pathinfo will return null if 0 or null is specified for the option argument.
So you'll need to define it's value manually if the option field is omitted, to provide the default functionality.
<?php
  public function getFileInfo($source = null, $option = null){
    if(!$option){
      //1 + 2 + 4
      $option = PATHINFO_DIRNAME + PATHINFO_BASENAME + PATHINFO_EXTENSION;
      if(defined('PATHINFO_FILENAME'))
        $option += PATHINFO_FILENAME; //8
    }
    return pathinfo($source, $option);
  }
  $obj->getFileInfo("/test/file/someFile.txt");
?>
A warning: this function varies depending on the platform it is being run on. For example, pathinfo('C:\Program Files\Adobe\Reader 9.0\Reader\AcroRd32.exe') will return a different result when run through a winOS PHP platform (local development) vs. a server's UNIX-based OS. A bit like the Locale settings, but unexpected.It's worth nothing that pathinfo returns foo/index.php for the directory when dealing with URLs like foo/index.php/bar
Note: dirname will be "." (meaning current directory) if the path is just a file name. (PHP 5.4.34)
<?php
var_dump( pathinfo('file.ext', PATHINFO_DIRNAME) ); // string(1) "."
?>
Sometimes, it's interessant to get the basename without extension.
So, I appended a new entry 'basenameWE' (Basename Without Extension) to the returned array.
<?php
// pathinfo improved
function pathinfo_im($path) {
  
  $tab = pathinfo($path);
  
  $tab["basenameWE"] = substr($tab["basename"],0
  ,strlen($tab["basename"]) - (strlen($tab["extension"]) + 1) );
  
  return $tab;
}
$my_path = "/var/www/html/example";
echo "<pre>\n";
print_r( pathinfo_im($my_path) );
echo "</pre>\n";
?>
Out :
Array
(
  [dirname] => /var/www/html
  [basename] => example.html
  [extension] => html
  [basenameWE] => example
)This function is not perfect, but you can use it to convert a relative path to a URL.
Please email me if you can make any improvements.
<?php
function mapURL($relPath) {
  $filePathName = realpath($relPath);
  $filePath = realpath(dirname($relPath));
  $basePath = realpath($_SERVER['DOCUMENT_ROOT']);
  
  // can not create URL for directory lower than DOCUMENT_ROOT
  if (strlen($basePath) > strlen($filePath)) {
    return '';
  }
  
  return 'http://' . $_SERVER['HTTP_HOST'] . substr($filePathName, strlen($basePath));
}
?>
<?php
// your code goes here
echo phpversion();
print_r(pathinfo("/resources/img/stock/wxb001/美景.png")); 
输出:
5.6.4-2
Array
(
  [dirname] => /resources/img/stock/wxb001
  [basename] => 美景.png
  [extension] => png
  [filename] => 美景
)
但是在php5.3.3版本中
<?php
// your code goes here
echo phpversion();
print_r(pathinfo("/resources/img/stock/wxb001/美景.png")); 
输出:
5.3.3
Array
(
  [dirname] => /var/www/www.shima.jp.net/resources/img/stock/wxb001
  [basename] => .png
  [extension] => png
  [filename] => 
)pathinfo() which can be used with UTF filenames.
<?php
 function pathinfo_utf($path)
 {
  if (strpos($path, '/') !== false) $basename = end(explode('/', $path));
  elseif (strpos($path, '\\') !== false) $basename = end(explode('\\', $path));
  else return false;
  if (empty($basename)) return false;
  $dirname = substr($path, 0, strlen($path) - strlen($basename) - 1);
  if (strpos($basename, '.') !== false)
  {
   $extension = end(explode('.', $path));
   $filename = substr($basename, 0, strlen($basename) - strlen($extension) - 1);
  }
  else
  {
   $extension = '';
   $filename = $basename;
  }
  return array
  (
   'dirname' => $dirname,
   'basename' => $basename,
   'extension' => $extension,
   'filename' => $filename
  );
 }
?>
For a good example of how platform independent this function is have a look at the different return values that Lostindream and I experienced. Mine is above and Lostindream's is below: Array ( [dirname] => /www/psychicblast/images/1 [basename] => my three girlfriends.jpg [extension] => jpg ) Array ( [dirname] => /www/htdocs [basename] => index.html [extension] => html [filename] => index ) z
Note that pathinfo($somePath, PATHINFO_EXTENSION) will return '' (empty string) for both of these paths: - some_random_file - another_strange_file_ending_in_dot. That's good, but then note that pathinfo($somePath, PATHINFO_FILENAME) won't end in the dot for 'another_strange_file_ending_in_dot.' - you'll need pathinfo($somePath, PATHINFO_BASENAME) to get the original filename ending in a dot. Hope this helps!
PHP equivalent for custom implementations. Will be nearly as fast or faster (with long paths):
<?php
$trimPath = rtrim($path, '/');
$slashPos = strrpos($trimPath, '/');
if ($slashPos !== false) {
  $dirName = substr($trimPath, 0, $slashPos) ?: '/';
  $baseName = substr($trimPath, $slashPos + 1);
} else {
  $dirName = '.';
  $baseName = $trimPath;
}
$dotPos = strrpos($baseName, '.');
if ($dotPos !== false) {
  $fileName = substr($baseName, 0, $dotPos);
  $extension = substr($baseName, $dotPos + 1);
} else {
  $extension = '';
  $fileName = $baseName;
}
?>
Further to my previous post. This affects servers that run PHP as a cgi module If you have your own server: You can use the AcceptPathInfo directive to force the core handler to accept requests with PATH_INFO and thereby restore the ability to use PATH_INFO in server-side includes. Further information: http://httpd.apache.org/docs-2.0/mod/core.html#acceptpathinfo
qutechie at gmail dot com wrote a fix for support for filename in PHP 4; however it gets it wrong whenever you have a filename with a . in it (so foo.bar.jpg would return foo instead of foo.bar).
A fix would be:
<?php
if(!isset($path_parts['filename'])){
  $reversed_filename = strrev( $path_parts['basename'] );
  $path_parts['filename'] = strrev( substr( $reversed_filename, strpos( $reversed_filename, '.' ) + 1 ) );
}
?>
The idea is that you reverse the string and create a substring that starts after the first '.' and then reverse the result.Quick fix for lack of support for 'filename' in php4
<?php
$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"; // since PHP 5.2.0
// if php4
       if(!isset($path_parts['filename'])){
        $path_parts['filename'] = substr($path_parts['basename'], 0,strpos($path_parts['basename'],'.'));
       }
?>
Lightweight way to get extension for *nix systems
<?php
function get_extension($path)
{
  $c = preg_match('#[^\/]+\.([^\.]*)$#uis', $path, $tmp);
  return $c ? $tmp[1] : null;
}
?>
this will return NULL for dotfiles (hidden files)
Testing:
<?php
$test = array(
  '/normal_dir/normal.foo',
  '/double_ext.foo.bar',
  '/.hidden/empty_ext.',
  '/.hidden_dir/.hidden_file',
  '/foo.bar/no_ext'
);
foreach($test as $path) {
  var_dump(parse_extension($path));
}
?>
results:
string(3) "foo"
string(3) "bar"
string(0) ""
NULL
NULL
if you want to get all extensions (substring of file name after first dot) use another expression:
<?php
$c = preg_match('#[^\.|\/]+\.([^\/]*)$#uis', $path, $tmp);
?>
