当文件名以重音开头时 basename() 失败
basename() fail when file name start by an accent
这里有一个简单的例子来说明这个问题:
print basename('léquipe.jpg'); // léquipe.jpg
print basename('équipe.jpg'); // quipe.jpg
我怎样才能避免这种不一致,并确保 basename()
会 return 给我整个文件名?
谢谢
试试这个(对于 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
事实证明这似乎是一个错误:https://bugs.php.net/bug.php?id=62119
如果第一个字符是非 ASCII 字符,该字符就会消失。如果路径本身中有非 ASCII 字符,它工作正常。
同样奇怪的是,这个问题只发生在 64 位 PHP 安装上:
- 64bit version(没有按预期工作)
- 32bit version(按预期工作)
要解决此问题,您可以使用 PHP manual comment:
提供的自定义函数
function mb_basename($file)
{
return end(explode('/',$file));
}
代码来自:“(删除)dot gmail dot com 上的(删除)dot nasretdinov”
好的,为了避免错误(在我的例子中)做一点改变:
function _basename($file){
$array=explode('/',$file);
if (is_array($array)){
return end($array);
}else{
return $file;
}
}
尽情享受 ;-)
使用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
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 ;
}
?>
这里有一个简单的例子来说明这个问题:
print basename('léquipe.jpg'); // léquipe.jpg
print basename('équipe.jpg'); // quipe.jpg
我怎样才能避免这种不一致,并确保 basename()
会 return 给我整个文件名?
谢谢
试试这个(对于 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
事实证明这似乎是一个错误:https://bugs.php.net/bug.php?id=62119
如果第一个字符是非 ASCII 字符,该字符就会消失。如果路径本身中有非 ASCII 字符,它工作正常。
同样奇怪的是,这个问题只发生在 64 位 PHP 安装上:
- 64bit version(没有按预期工作)
- 32bit version(按预期工作)
要解决此问题,您可以使用 PHP manual comment:
提供的自定义函数function mb_basename($file)
{
return end(explode('/',$file));
}
代码来自:“(删除)dot gmail dot com 上的(删除)dot nasretdinov”
好的,为了避免错误(在我的例子中)做一点改变:
function _basename($file){
$array=explode('/',$file);
if (is_array($array)){
return end($array);
}else{
return $file;
}
}
尽情享受 ;-)
使用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
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 ;
}
?>