pathinfo
(PHP 4 >= 4.0.3, PHP 5, PHP 7, PHP 8)
pathinfo — 返回文件路径的信息
说明
$path
, int $flags
= PATHINFO_ALL
): array|string
pathinfo() 返回一个关联数组包含有 path
的信息。返回关联数组还是字符串取决于 flags
。
注意:
有关取得当前路径信息的说明,请阅读 预定义变量 一节。
注意:
pathinfo() 纯粹基于输入字符串操作, 它不会受实际文件系统和类似 "
..
" 的路径格式影响。
pathinfo() 是本地化的,所以为了让它能正确地解析一个包含多字节编码的路径, 必须使用 setlocale() 函数来设置地区信息。
参数
-
path
-
要解析的路径。
-
flags
-
如果指定了,将会返回指定元素;它们包括:
PATHINFO_DIRNAME
、PATHINFO_BASENAME
、PATHINFO_EXTENSION
、PATHINFO_FILENAME
。如果没有指定
flags
默认是返回全部的单元。
返回值
如果没有传入 options
,将会返回包括以下单元的数组 array:dirname
,basename
和 extension
(如果有),以及filename
。
注意:
如果
path
有一个以上的扩展名,PATHINFO_EXTENSION
只返回最后一个,而PATHINFO_FILENAME
仅剥离最后一个。 (参考第一个示例)。
注意:
如果
path
没有扩展名,返回数据中就不会有extension
元素。(参考第二个示例)
注意:
如果
path
中的basename
以点开始, 那后面的字符串将被解释为extension
, 并且filename
为空。(参考第三个示例)
如果 flags
存在的,
则返回一个包含请求元素的 string。
范例
示例 #1 pathinfo() 例子
<?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";
?>
以上例程会输出:
/www/htdocs/inc lib.inc.php php lib.inc
示例 #2 pathinfo() 对比空扩展名和无扩展名之间区别的示例
<?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
示例 #3 pathinfo() 形如 .file 的示例
<?php
print_r(pathinfo('/some/path/.test'));
?>
以上例程的输出类似于:
Array ( [dirname] => /some/path [basename] => .test [extension] => test [filename] => )
参见
- dirname() - 返回路径中的目录部分
- basename() - 返回路径中的文件名部分
- parse_url() - 解析 URL,返回其组成部分
- realpath() - 返回规范化的绝对路径名

User Contributed Notes 37 notes
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" }
unexpected, but longtime (all versions?) consistent, behaviour with trailing slash (Linux):
with Linux I am used, to add a trailing slash,
or just to keep that of the command line completion by [TAB],
to avoid mistyping a path on cp or mv with a same filename instead of a directory
using CLI '$ php -a' the result is in the next line
(but can also be done by script, webserver, etc.)
<?php // using php tags here only for syntax highlighting
// assuming getcwd() is /home/USER/ with existing subdir www.2021-05/
// cause path must exist, else 'false'
php > echo realpath('www.2021-05/');
/home/USER/www.2021-05
php > var_dump(pathinfo('/home/USER/www.2021-05/'));
array(4) {
["dirname"]=> string(10) "/home/USER"
["basename"]=> string(11) "www.2021-05"
["extension"]=> string(7) "2021-05"
["filename"]=> string(3) "www"
}
php > echo dirname('/home/USER/www.2021-05/');
/home/USER
php > echo basename('/home/USER/www.2021-05/');
www.2021-05
?>
with my own written functions, I would first split path from filename at the
_last_ slash (plus some extra for root-slash only);
which would find NO filename, only dirname path, in that example
for cross reference:
once reported on Win2k -- https://bugs.php.net/bug.php?id=41834
said to be heritage -- https://bugs.php.net/bug.php?id=81079
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;
}
?>
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 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.gz
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] => 飛兒樂團光茫
)
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;
}
?>
//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 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 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] =>
)
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.
at 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
)
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)
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 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,'.'));
}
?>
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);
?>
It's worth nothing that pathinfo returns foo/index.php for the directory when dealing with URLs like foo/index.php/bar
When you need to get the file extension to upload a file with a <form> POST method, try this way:
// $_FILES['archivo'] receives the <input> file (named 'archivo'), ['name'] gets the file name.
$nombre = $_FILES['archivo']['name'];
//['tmp_name] gets the temporal name of the file (not the real name), which will be used later
$nombre_temporal = $_FILES['archivo']['tmp_name'];
//Here is the magic of pathinfo to get the file extension
$extension = pathinfo($nombre, PATHINFO_EXTENSION);
$nombre_final = $nombre. ".". $extension;
// $ruta is where you want to save the file
$ruta = "subidos/".$nombre_final;
move_uploaded_file($nombre_temporal, $ruta);
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.html";
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
)
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) "."
?>
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.
extract(pathinfo("storage/example.pdf"));
echo $dirname; // "storage/"
echo $basename; // "example.pdf"
echo $extension; // "pdf"
echo $filename; // "example"
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
// 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] =>
)
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));
}
?>
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
);
}
?>
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
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 '/'
?>
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
<?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";
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;
}
?>
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);
?>
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";