Php 当文件名以重音开头时,basename()失败

Php 当文件名以重音开头时,basename()失败,php,filenames,Php,Filenames,下面是一个快速示例来说明问题: print basename('léquipe.jpg'); // léquipe.jpg print basename('équipe.jpg'); // quipe.jpg 如何避免这种不一致,并确保basename()将返回整个文件名 谢谢尝试此操作(对于windows server替换“/”): 因此,事实证明这似乎是一个bug: 如果第一个字符是非ASCII字符,则该字符将消失。如果路径本身中有非ASCII字符,则可以正常工作 另外,似乎奇怪的是,这

下面是一个快速示例来说明问题:

print basename('léquipe.jpg'); // léquipe.jpg
print basename('équipe.jpg');  // quipe.jpg
如何避免这种不一致,并确保
basename()
将返回整个文件名

谢谢

尝试此操作(对于windows server替换“/”):


因此,事实证明这似乎是一个bug:

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

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

  • (未按预期工作)
  • (按预期工作)
要解决此问题,您可以使用以下提供的自定义函数:


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

好的,为避免错误(在我的例子中)做了一些小改动:

享受;-)

用于解决此问题

setlocale(LC_CTYPE, 'fr_FR.utf8');

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

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

测试输出:

________________________________________________________
‾‾ 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 ;
}
?>


您使用的是什么编码?我认为您应该查看php.ini并添加
mbstring.internal_encoding=utf-8
检查此项,以“避免”您可以简单地在ascii字符('a')前面加上前缀。我在任何地方都使用utf8,因此它应该是相同的,但我不知道确切的
机制。想给他们至少学分吗?(还有发生这种情况的原因是什么?)很抱歉,没有提供到源页面的链接。这是因为函数basename和pathinfo无法与UTF中的文件名一起工作。您保存了我的一天,谢谢:+1:
setlocale(LC_CTYPE, 'fr_FR.utf8');

print basename('léquipe.jpg'); // léquipe.jpg
print basename('équipe.jpg');  // équipe.jpg
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;
    }
}
________________________________________________________
‾‾ 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 ;
}
?>