• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 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_DIRNAMEPATHINFO_BASENAMEPATHINFO_EXTENSIONPATHINFO_FILENAME

    如果没有指定$options默认是返回全部的单元。

    返回值

    如果没有传入$options,将会返回包括以下单元的数组array:dirnamebasenameextension(如果有),以及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.

    参见

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

    上篇:parse_ini_string()

    下篇:pclose()