文件名在通过PHP上传后在FTP中包含奇怪的字符

文件名在通过PHP上传后在FTP中包含奇怪的字符,php,file-upload,encoding,character-encoding,Php,File Upload,Encoding,Character Encoding,我通过PHP将我的曲目上传到我的服务器,现在它在WinSCP中显示为: Dubmood-Mario航空公司(Razor1911 Crysis-Keygen编辑)。mp3 当我通过PuTTY运行ls-ls时,它通常显示为: Dubmood-马里奥航空公司(Razor1911 Crysis​-​键盘编辑)。mp3 PHP称之为: Dubmood-马里奥航空公司(Razor1911 Crysis?-?Keygen编辑)。mp3 我不知道是什么导致了这个问题,我尝试使用 $_FILES['audiofi

我通过PHP将我的曲目上传到我的服务器,现在它在WinSCP中显示为:

Dubmood-Mario航空公司(Razor1911 Crysis-Keygen编辑)。mp3

当我通过PuTTY运行
ls-ls
时,它通常显示为:

Dubmood-马里奥航空公司(Razor1911 Crysis​-​键盘编辑)。mp3

PHP称之为:

Dubmood-马里奥航空公司(Razor1911 Crysis?-?Keygen编辑)。mp3

我不知道是什么导致了这个问题,我尝试使用

$_FILES['audiofile']['name'] = mb_convert_encoding($_FILES['audiofile']['name'], "UTF-8");
但这似乎没什么作用


是什么导致了这个问题?我如何解决它?

这是由php使用UTF-8这一事实造成的。如果您的文件名有任何字符>=char(128),那么它将成为php中的两个(或更多)字节序列。因此,您的名称由–组成,实际上是服务器上的一个字符。为了正确上传,必须转换文件名(在php中)。 假设我有一个从我的网站输入的字符串: 我的代码这就是我的代码 可以使用utf8\U编码将其转换为我的代码 您的文件系统(假设它是windows)运行在iso-8859-1 win-1252或类似的版本上(通常使用双字节字符,假设您有一个现代windows)。 因此,您需要将文件名转换为符合服务器字符集的文件。您可以使用iconv来实现这一点。 当然,您也可以将其更改为iso-8859-1或任何其他代码页

用于测试的一段代码:

$s='Dit&is een+code#met%vreemdeÝ×tekens';
echo 'raw string:'.$s."\n";
echo 'filename_normal:'.filename_normal($s)."\n";
echo 'utf8-encode:'.utf8_encode($s)."\n";
echo 'iconv:'.iconv('UTF-8','ISO-8859-1//IGNORE',$s)."\n";
echo 'mb_internal_encoding:'.mb_internal_encoding();
这将提供以下输出

raw string:Dit&is een+code#met%vreemde▌╫tekens
Dit&is een+code#met%vreemde▌╫tekens
filename_normal:Dit en is een + code_met vreemde  tekens
utf8-encode:Dit&is een+code#met%vreemdeÝ×tekens
iconv:Dit&is een+code#met%vreemdetekens
mb_internal_encoding:ISO-8859-1
是的,我忘记了你的正常

function filename_normal($s)
{
  echo $s . "\n";
  $t='';
  for ($i=0;$i<strlen($s);$i++){
    if (ord(substr($s,$i,1))<32){
      $t=$t.' ';
    }elseif (ord(substr($s,$i,1))>127){
      $t=$t.' ';
    }elseif (substr($s,$i,1)=='&'){
      $t=$t.' en ';
    }elseif (substr($s,$i,1)=='+'){
      $t=$t.' + ';
    }elseif (substr($s,$i,1)=='%'){
      $t=$t.' ';
    }elseif (substr($s,$i,1)=='#'){
      $t=$t.'_';
    }else
      $t=$t.substr($s,$i,1);

  }
  return $t;
}
函数文件名\u正常($s)
{
回显$s。“\n”;
$t='';

对于($i=0;$i),这可能不是修复它的最佳方法,但对我来说很有效

$s = preg_replace("([^a-zA-Z0-9-_. \(\)])", "", $s);
filename_normal()函数不是PHP内部函数,其他函数对我来说没有任何更改不幸的是,问题是(我认为)我的字符串已经是UTF-8,这是我的服务器输出的内容: