PHP - Windows - 上传后文件名不正确(ü 保存为 ü 等) [英] PHP - Windows - filename incorrect after upload (ü saved as ü etc.)

查看:31
本文介绍了PHP - Windows - 上传后文件名不正确(ü 保存为 ü 等)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个允许上传多个文件的自制应用程序,我使用 AJAX 将文件传递给 php,使用 php 创建新目录,将上传的文件移到那里并将目录位置保存到数据库.然后查看我运行的文件,列出了保存在 db 中的目录位置.

I have this home made app that allows multiple file uploads, I pass the files to php with AJAX, create new dir with php, move there uploaded files and save the dir location to database. Then to see the files I run listing of the directory location saved in the db.

问题在于文件来自世界各地,因此它们经常包含一些非拉丁字符,例如 ü.当我回显 php 名​​称中的文件名时,即使它们的名称是用阿拉伯语书写的,它们也会正确显示,但它们以编码名称保存在服务器上,例如 ü 代替 ü.当我列出目录中的文件时,我可以看到 ü.txt 的名称为 ü.txt,但是当我点击它时,服务器返回未找到的错误对象(因为在服务器上它被保存为ü.txt).

The problem is that files come from all around the world so very often they have some non latin characters like for example ü. When I echo the filename in php names appear correctly even when they have names written in Arabic, yet they are being saved on the server with encoded names as for example ü in place of ü. When I list the files from directory I can see the name ü.txt insted of ü.txt but when I click on it server returns error object not found (since on the server it is saved as ü.txt and it reads the link as ü.txt).

我尝试了一些建议的解决方案,例如使用 iconv,但文件名仍然以相同的方式保存.

I tried some of the suggested solutions as for example using iconv, but the filenames are still being saved the same way.

我可以发誓,当 Web 应用程序托管在 linux 上时,问题不存在,但目前我不再那么确定了.现在我暂时在 xampp(在 Windows 上)上运行它,似乎文件名是使用 windows-1252 编码(服务器上的默认 Windows 编码)保存的.是否是默认的 Windows 编码相关问题?

I could swear the problem wasn't present when the web app was hosted on linux, but at the moment I am not so sure about it anymore. Right now I temporarily run it on xampp (on Windows) and it seems like filenames are saved using windows-1252 encoding (default Windows' encoding on the server). Is it default Windows encoding related problem?

老实说,我不知道如何解决这个问题,我将不胜感激.我应该继续尝试以不同的字符编码保存文件,还是最好以不同的方式处理它并更改列出已保存和编码文件的方式?

To be honest I do not know how to approach that problem and I would appreciate any help. Should I keep on trying to save the files in different character encoding or would it be better to approach it different way and change the manner of listing the already saved and encoded files?

编辑.根据(最终)关闭的错误报告,它已在 php 7.1 中修复.

EDIT. According to the (finally) closed bug report it was fixed in php 7.1.

推荐答案

最后我用以下方法解决了:

In the end I solved it with the following approach:

  1. 上传文件时,我使用 rawurlencode()
  2. 对名称进行 urlencode
  3. 当从服务器获取文件时,它们显然是 URL 编码的,所以我使用 urldecode($filename) 打印正确的名称
  4. a href 中的链接会自动翻译,因此例如%20"变成了",而 URL 最终不正确,因为它链接到错误的文件名.我决定将它们编码回来并打印出来,结果如下: print $dirReceived.rawurlencode($file); ($dirReceived 是存储接收文件的目录,在代码前面定义)
  5. 我还使用 urldecode($filename) 添加了下载属性,以便在需要时使用 UTF-8 名称保存文件.
  1. When uploading the files I urlencode the names with rawurlencode()
  2. When fetching the files from server they are obviously URL encoded so I use urldecode($filename) to print correct names
  3. Links in a href are automatically translated, so for example "%20" becomes a " " and URL ends up being incorrect since it links to incorrect filename. I decided to encode them back and print them ending up with something like this: print $dirReceived.rawurlencode($file); ($dirReceived is the directory where received files are stored, defined earlier in the code)
  4. I also added download attribute with urldecode($filename) to save the file with UTF-8 name when needed.

多亏了这一点,我在服务器上保存了带有 url 编码名称的文件.可以在浏览器中打开它们(非常重要,因为它们中的大多数都是 *.pdf)并且可以使用正确的名称下载它们,这让我可以上传和下载名称以阿拉伯语、西里尔文等书写的文件.

Thanks to this I have files saved on the server with url encoded names. Can open them in browser (very important as most of them are *.pdf) and can download them with correct name which lets me upload and download even files with names written in Arabic, Cyrillic, etc.

到目前为止,我对其进行了测试,看起来不错.我正在考虑在生产代码中实现它.对此有任何顾虑/想法吗?

So far I tested it and looks good. I am thinking of implementing it in production code. Any concerns/thoughts on it?

编辑.

由于没有人反对,我选择我的答案作为解决我问题的答案.在做了一些测试之后,客户端和服务器端的一切看起来都不错.在服务器上保存文件时,它们是 URL 编码的,下载时它们被解码并以正确的名称保存.

Since there are no objections I select my answer as the one that solved my problem. After doing some testing everything looks good on client and server side. When saving the files on server they are URL encoded, when downloading them they are decoded and saved with correct names.

一开始我使用的是代码:

At the beginning I was using the code:

    for($i=0;$i<count($_FILES['file']['name']);$i++) 
{
    move_uploaded_file($_FILES['file']['tmp_name'][$i],
    "../filepath/" . $_FILES['file']['name'][$i]);
}

此方法在保存文件时出现问题,并将每个 UTF-8 特殊字符替换为 cp1252 编码的字符(ü 保存为 ü 等),因此我添加了一行并将该代码替换为以下内容:

This method caused the problem upon saving file and replaced every UTF-8 special character with cp1252 encoded one (ü saved as ü etc.), so I added one line and replaced that code with the following:

for($i=0;$i<count($_FILES['file']['name']);$i++) 
{
    $fname= rawurlencode($_FILES['file']['name'][$i]);
    move_uploaded_file($_FILES['file']['tmp_name'][$i],
    "../filepath/" . $fname);
}

这允许我使用与 cp1252 和 UTF-8 兼容的 URL 编码(% 和两个十六进制)在服务器上保存任何文件名.

This allows me to save any filename on server using URL encoding (% and two hexadecimals) which is compatible with both cp1252 and UTF-8.

要列出已保存的文件,我使用已保存在数据库中的文件路径并为文件列出它们.我正在使用以下代码:

To list the saved files I use filepaths I have saved in DB and list them for files. I was using the following code:

    if (is_dir($dir)){
  if ($dh = opendir($dir)){
    while (($file = readdir($dh)) !== false){
        if(is_file($dir . $file)){

    echo "<li><a href='".$dir.$file."' download='".$file ."'>".$file."</a></li><br />";

    }
}
    closedir($dh);
  }
}

由于 URL 编码的文件名是自动解码的,我将其更改为:

Since URL encoded filenames were decoded automatically I changed it to:

    if (is_dir($dir)){
  if ($dh = opendir($dir)){
    while (($file = readdir($dh)) !== false){
        if(is_file($dir . $file)){
            echo "<li><a href='";
            print $dir.rawurlencode($file);
            echo "' download='" . urldecode($file) ."'>".urldecode($file)."</a></li><br />";
    }
}
    closedir($dh);
  }
}

我不知道这是否是解决问题的最佳方法,但效果很好,我也知道不使用 php 生成 html 标签通常是一个好习惯,但目前我有一些严重的错误需要先解决这个问题,然后我必须处理代码本身的外观.

I don't know if this is the best way to solve it but works perfectly, also I am aware that it is generally a good practice not to use php to generate html tags but at the moment I have some critical bugs that need addressing so first that and then I'll have to work on the appearance of the code itself.

编辑2

另外一个好处是我不必更改已上传文件的名称,这对我来说是一个很大的优势.

Also the great thing is I do not have to change names of the already uploaded files which in my case is a big advantage.

这篇关于PHP - Windows - 上传后文件名不正确(&amp;#252; 保存为 &amp;#195;&amp;#188; 等)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆