【问题标题】:PHP - Upload utf-8 filenamePHP - 上传 utf-8 文件名
【发布时间】:2013-08-13 08:38:16
【问题描述】:

我是越南人,我想上传一个像这样的 utf-8 文件名

Tên Tệp Tiếng Việt.JPG

这是我的代码

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
<title>utf-8</title> 
</head> 

<body> 
<?php
    if(isset($_POST["submit"])) { 
       if($_FILES["upload"]["error"] > 0 ) echo "FILE ERROR!"; 
       else 
         { 
           $base_dir = "D:/"; 
           $fn = $_FILES["upload"]["name"]; 

           $fn2 = $base_dir.$fn;

           move_uploaded_file($_FILES["upload"]["tmp_name"],$fn2); 
         } 
     } 
?> 
<form action="" method="post" enctype="multipart/form-data" name="form1" id="form1"> 
  <input type="file" name="upload" id="upload" /> 
  <input type="submit" name="submit" id="submit" value="Send" /> 
</form> 
</body> 
</html> 

但是当我上传时,我在我的电脑上看到 D:\ 有一个类似的文件

Tên Tệp Tiếng Việt.JPG

如何解决这个问题,谢谢

【问题讨论】:

  • 在 Windows 上,您可能必须使用 iconv() 将其转换为 ucs2
  • @Jack 我尝试 ` $fn2 = iconv("UTF-8","ucs2", $base_dir.$fn) ;` 但得到错误 iconv(): Wrong charset, conversion from @987654324 @ucs2' 不允许?
  • 其实是UCS-2 :)
  • 我将其编辑为 $fn2 = iconv("UTF-8","UCS-2", $base_dir.$fn);但我收到新错误move_uploaded_file(): Filename cannot be empty ..move_uploaded_file(): Unable to move 'E:\PHP\Xampp\tmp\php6B2C.tmp' ...?怎么了
  • 第一件事。你能echo你在服务器上收到的文件名吗?测试文件名是否上传 UTF-8 编码?因为 那个 部分可能正在工作。问题是 PHP 在写入文件时如何与文件系统交互,这基本上取决于底层文件系统所做的事情,这在 Windows 的情况下可能非常丑陋和复杂。如果文件名在 UTF-8 中上传很好,问题就变成了“如何在 UTF-8 中编写文件名”,答案可能不太好。跨度>

标签: php file-upload character-encoding upload


【解决方案1】:

我使用的是 Windows 8 中文版,我遇到了类似的问题:

$filename = iconv("utf-8", "cp936", $filename);

cp代表Code pagecp936代表Code page 936,这是Windows简体中文版的默认代码页。

所以我想也许你的问题可以用类似的方式解决:

$fn2 = iconv("UTF-8","cp1258", $base_dir.$fn);

我不太确定您的操作系统的默认代码页是否为1258,您应该通过打开命令提示符并输入命令chcp 自行检查。然后将1258 更改为命令给您的任何内容。

更新

根据this answer,似乎 PHP 文件系统函数只能处理系统代码页中的字符。所以你在这里有两个选择:

  1. 将文件名中的字符限制为系统代码页 - 在您的情况下,它是 437。但我很确定代码页 437 不包含所有越南语字符。

  2. 将您的系统代码页更改为越南语:1258,并将文件名转换为cp1258。然后文件系统功能应该可以工作了。

两种选择都有缺陷:

选择 1:您不能再使用越南语字符,这不是您想要的。

选择 2:您必须更改系统代码页,文件名字符仅限于代码页 1258。

更新

如何更改系统代码页:

转到Control Panel > Region > Administrative > Change system locale 并在下拉菜单中选择Vietnamese(Vietnam)

【讨论】:

  • +1 因为我认为这个答案正朝着正确的方向发展。由于您需要为要使用的字符集选择正确的代码页,因此这当然很难一概而论。
  • 我尝试给出:Active code page: 437,然后我更改为$fn2 = iconv("UTF-8","cp437", $base_dir.$fn);,并给出Notice: iconv(): Detected an illegal character in input string in 之类的错误和Warning: move_uploaded_file(): Filename cannot be empty 之类的一些警告...?
  • @trungkien 现在我也不知道。试试cp1258,也许?
  • 运行起来比以前更好了 :( 但仍然不是 utf-8
  • 我关注superuser.com/questions/269818/… 将代码页更改为1258。第一个我只是在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Nls\CodePage\OEMCP 中更改。但是第二个,我在HKEY_LOCAL_MACHINE\Software\Microsoft\Command Processor\Autorun 中找不到Autorun
【解决方案2】:

这个meta没有效果:

&lt;meta http-equiv="Content-Type" content="text/html; charset=utf-8" /&gt;

因为 Web 服务器已经发送了Content-Type 标头,因此决定了编码是什么。 Web 浏览器以相同的编码发送表单。 meta 在用户离线时很有用。

所以你必须自己sned http header Content-Type

<?php header("Content-Type: text/html; charset=utf-8"); ?>

确保将其放在任何 html、内容或发送的任何内容之前。


或者,form 上的 accept-charset 标记应该可以正常工作:

 <form accept-charset="utf-8"> 

【讨论】:

  • 我添加了 首先是文件(文件是我的问题中的代码)但没有任何作用:(
  • @trungkien 你用的是什么浏览器?尝试观察网络流量,尤其是在发送表单时,检查发送的(来自浏览器)content-type 标头。有charset 吗?您也可以尝试将accept-charset="utf-8" 添加到&lt;form&gt;
  • 我正在使用火狐。如何查看网络流量?我使用萤火虫,然后转到:Net&gt;All&gt;Headers&gt;Response Headers,我在Response Headers 上看到Content-Type text/html; charset=utf-8。我尝试添加 accept-charset="utf-8" 但不工作。这是我的upload.php 文件jsfiddle.net/nnBwV
  • @trungkien 好的,我的意思是content-typeRequest Hedears,看看那里。
  • 在选项Request Headers From Upload StreamContent-Type multipart/form-data; boundary=---------------------------18199138701329 ??
【解决方案3】:

我是波斯人,我的语言中的 utf-8 字符也有同样的问题。 我可以用这段代码解决我的问题:

$fn = $_FILES["upload"]["name"]; // name of file have some utf-8 characters
$name=iconv('utf-8','windows-1256', str_replace('ی', 'ي', $fn));
move_uploaded_file($_FILES["upload"]["tmp_name"],$name );

我不确定关于 vientam 语言,但也许您可以使用与上面相同的代码并进行一些更改:

$fn = $_FILES["upload"]["name"]; // name of file have some utf-8 characters
$name=iconv('utf-8','cp936', $fn);
move_uploaded_file($_FILES["upload"]["tmp_name"],$name );

【讨论】:

    【解决方案4】:

    目前为止我找到的唯一解决方案..(2014 年):

    1) 我不在我的 FTP 上以 UTF-8 字符串 存储文件。相反,我使用这个函数来重命名上传的文件:

    <?php
    // use your custom function.. for example, utf8_encode
    $newname  = utf8_encode($_FILES["uploadFile"]["name"]);
    move_uploaded_file($_FILES["uploadFile"]["tmp_name"], $newname);
    ?> 
    

    2) 现在您可以重命名(或等)$newname;

    【讨论】:

    • 它在 Windows 上不起作用
    【解决方案5】:

    首先要检测文件名编码(在上传之前)。

    print_r($_FILES["upload"]);
    

    将文件名插入decoder 并检查编码。

    【讨论】:

      【解决方案6】:

      对不起!你的问题是关于文件名的。

      你必须用 iconv 保存你的文件名,但没有这个。

      保存:

      <?php
      $name = $_FILES['photo']['name'];
      $unicode = iconv('windows-1256', 'utf-8', $name);
      move_uploaded_file($_FILES['photo']['tmp_name'], 'photos/' . $name);
      mysql_query("INSERT INTO `photos` (`filename`) VALUES ('{$unicode}')");
      ?>
      

      阅读:

      <?php
      $images = mysql_query('SELECT * FROM `photos`');
      if($images && mysql_num_rows($images) > 0) {
          while($image = mysql_fetch_assoc($images)) {
              $name = iconv('utf-8', 'windows-1256', $image['filename']);
              echo '<img src="photos/' . $name . '"/>';
          }
          mysql_free_result($images);
      }?>
      

      【讨论】:

        【解决方案7】:
        function convToUtf8($str) 
        { 
        if( mb_detect_encoding($str,"UTF-8, ISO-8859-1, GBK")!="UTF-8" ) 
        { 
        
        return  iconv("gbk","utf-8",$str); 
        
        } 
        else 
        { 
        return $str; 
        } 
        
        }
        
        
        $filename= convToUtf8($filename) ;
        

        【讨论】:

          【解决方案8】:

          试试这个

          $imgname     = $_FILES['img'] ['name'] ;
          $imgsize     = $_FILES['img'] ['size'] ;
          $imgtmpname  = $_FILES['img'] ['tmp_name'] ;
          $imgtype     = $_FILES['img'] ['type'] ;
          $size     = 1024;
          $imgtypes    = array('image/jpeg','image/gif','image/png');
          $folder = "up";
          
          if(empty($imgname)){
            echo "Shose ur photo";
          }else if(!in_array($imgtype,$imgtypes)){
            echo "this photo type is not avalable";
          }else if($imgsize > $size){
            echo "this photo is dig than 6 MB";
          }else if($imgwidth > 5000){
          echo "the file is to big";
          }
          else{
           move_uploaded_file($imgtmpname, $folder, $filename); 
          }
          

          【讨论】:

          • 抱歉,我的问题是关于在我的计算机上存储文件的 utf-8 名称?
          【解决方案9】:

          你可以用这个

          $fn2 = basename($_FILES['upload']['name']);
          

          【讨论】:

          • 解决不了蚂蚁问题,小心你说的话!
          猜你喜欢
          • 2013-06-04
          • 1970-01-01
          • 2018-09-21
          • 1970-01-01
          • 2013-12-22
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多