【问题标题】:basename() fail when file name start by an accent当文件名以重音开头时,basename() 失败
【发布时间】:2023-03-31 11:52:01
【问题描述】:

这是一个显示问题的简单示例:

print basename('léquipe.jpg'); // léquipe.jpg
print basename('équipe.jpg');  // quipe.jpg

我怎样才能避免这种不一致,并确保basename() 会返回给我完整的文件名?

谢谢

【问题讨论】:

  • 你用的是什么编码?
  • 我认为你应该看看你的 php.ini 并添加 mbstring.internal_encoding=utf-8
  • 查看link
  • 为了“避免”,您可以简单地在前面加上一个 ascii 字符 ('a')。
  • 我在所有地方都使用 utf8,所以它应该是一样的,但我不知道确切的 <input type="file"> 机制。

标签: php filenames


【解决方案1】:

事实证明这似乎是一个错误:https://bugs.php.net/bug.php?id=62119

如果第一个字符是非 ASCII 字符,该字符就会消失。如果路径本身中有非 ASCII 字符,它可以正常工作。

另外似乎很奇怪的是,这个问题只发生在 64 位 PHP 安装中:

要解决这个问题,您可以使用PHP manual comment 提供的自定义函数:

function mb_basename($file) 
{ 
    return end(explode('/',$file)); 
} 

代码来自:“(remove) dot nasretdinov at (remove) dot gmail dot com”

【讨论】:

    【解决方案2】:

    使用http://php.net/manual/en/function.setlocale.php来解决这个问题。

    setlocale(LC_CTYPE, 'fr_FR.utf8');
    
    print basename('léquipe.jpg'); // léquipe.jpg
    print basename('équipe.jpg');  // équipe.jpg
    

    【讨论】:

    • 你拯救了我的一天,谢谢 :+1:
    【解决方案3】:

    试试这个(对于 windows 服务器替换 '/'):

    function mb_basename($file)
    {
      $temp = explode('/', $file);
      return end($temp);
    }
    print mb_basename('léquipe.jpg'); // léquipe.jpg
    print mb_basename('équipe.jpg');  // équipe.jpg
    

    【讨论】:

    • 想给他们至少学分:php.net/manual/en/function.basename.php#85369? (还有什么原因导致这种情况发生?)
    • 很抱歉没有提供指向源页面的链接。发生这种情况是因为函数 basename 和 pathinfo 不能使用 UTF 中的文件名
    【解决方案4】:

    好的,稍作改动以避免错误(在我的情况下):

    function _basename($file){
        $array=explode('/',$file);
        if (is_array($array)){
            return end($array);
        }else{
            return $file;
        }
    } 
    

    享受 ;-)

    【讨论】:

      【解决方案5】:
      if( !function_exists( "mb_basename")){
          function mb_basename( $file, $ext){
              $file = explode( '/', $file);
              $file = end( $file);
              if( $ext){
                  $p = strripos( $file, $ext);
                  if( $p !== false && $p == strlen( $file) -strlen( $ext))$file = substr( $file, 0, $p);
              }
              return $file;
          }
      }
      

      【讨论】:

        【解决方案6】:

        此提案处理后缀参数和测试列表。注意尾随的“/”行为。

        测试输出:

        ________________________________________________________
        ‾‾ basename ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
        0) sudoers
        1) sudoers.d
        2) passwd
        3) etc
        4) .
        5) 
        6) ..
        7) lément
        8) lément.txt
        9) lément.TXT
        10) lément.jpg
        11) quipe
        12) quipe
        ________________________________________________________
        ‾‾ mb_basename ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
        0) sudoers
        1) sudoers.d
        2) passwd
        3) etc
        4) .
        5) 
        6) ..
        7) élément
        8) élément.txt
        9) élément.TXT
        10) élément.jpg
        11) équipe
        12) équipe
        

        源代码:

        <?php
        if ( ! function_exists ( 'mb_basename' ) ) {
            function mb_basename ( $path, $suffix='' ) {
                $array = explode ( '/', rtrim( $path, '/' ) ) ;
                $basename = end ( $array ) ;
                if( ! empty ( $suffix ) ) {
                    $slen = strlen ( $suffix ) ;
                    if ( substr ( $basename, -$slen, $slen) == $suffix ) {
                        $basename = substr ( $basename, 0, -$slen ) ;
                    }
                }
                return $basename;
            }
        }
        
        // https://www.php.net/manual/en/function.basename.php#example-2871
        $tests = array (
            array ( '/etc/sudoers.d', '.d' ),
            array ( '/etc/sudoers.d' ),
            array ( '/etc/passwd' ),
            array ( '/etc/' ),
            array ( '.' ),
            array ( '/' ),
            array ( '..' ),
            array ( '/home/user/équipe/élément.txt', '.txt' ),
            array ( '/home/user/équipe/élément.txt', '.TXT' ),
            array ( '/home/user/équipe/élément.TXT', '.txt' ),
            array ( '/home/user/équipe/élément.jpg', '.txt' ),
            array ( '/home/user/équipe/' ),
            array ( '/home/user/équipe' ),
        );
        echo '________________________________________________________'.PHP_EOL ;
        echo '‾‾ basename ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'.PHP_EOL ;
        foreach ( $tests as $key => $test ) {
            echo $key .') '. basename ( $test[0], @$test[1] ) .PHP_EOL ;
        }
        echo '________________________________________________________'.PHP_EOL ;
        echo '‾‾ mb_basename ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾'.PHP_EOL ;
        foreach ( $tests as $key => $test ) {
            echo $key .') '. mb_basename ( $test[0], @$test[1] ) .PHP_EOL ;
        }
        ?>
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-12-08
          • 2020-04-12
          • 1970-01-01
          • 2018-06-18
          • 2018-08-05
          • 1970-01-01
          相关资源
          最近更新 更多