extract(pathinfo("storage/example.pdf"));
echo $dirname; // "storage/"
echo $basename; // "example.pdf"
echo $extension; // "pdf"
echo $filename; // "example"
(PHP 4 >= 4.0.3, PHP 5, PHP 7)
pathinfo — 返回文件路径的信息
$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
path
does not have an extension, no extension element will be returned(以下第二个案例)。
If options
is present, returns a
string containing the requested element.
版本 | 说明 |
---|---|
5.2.0 |
添加了常量 PATHINFO_FILENAME 。
|
Example #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"; // since PHP 5.2.0
?>
以上例程会输出:
/www/htdocs/inc lib.inc.php php lib.inc
Example #2 pathinfo() 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 the setlocale() function.
extract(pathinfo("storage/example.pdf"));
echo $dirname; // "storage/"
echo $basename; // "example.pdf"
echo $extension; // "pdf"
echo $filename; // "example"
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";
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";
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 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!
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);
?>
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" }
<?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] =>
)
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;
}
?>
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) "."
?>
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] => 飛兒樂團光茫
)
It's worth nothing that pathinfo returns foo/index.php for the directory when dealing with URLs like foo/index.php/bar
//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
*/
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;
}
?>
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");
?>
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() 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
);
}
?>
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;
}
?>
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,'.'));
}
?>
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
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.
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
)
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'],'.'));
}
?>
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
)
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));
}
?>
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] =>
)
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.
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
)
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
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.
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
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);
?>