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.gz
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 )
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); ?>