Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/242.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 图像URL中的unicode字符-404_Php_Html_Unicode_Url Encoding - Fatal编程技术网

Php 图像URL中的unicode字符-404

Php 图像URL中的unicode字符-404,php,html,unicode,url-encoding,Php,Html,Unicode,Url Encoding,我试图打开一个名称中有拉丁字符的图像(113_Atlético Madrid) 我通过使用PHP函数rawurlencode()对其名称进行编码来保存它,因此现在它的新名称是113_Atl%C3%A9tico%20Madrid。但是当我试图通过这个URL打开它时,例如mysite.com/images/113_Atl%C3%A9tico%20Madrid.png我得到了404个错误 我如何解决这个问题 PHP代码: if(isset($_FILES['Team'])){ $avatar

我试图打开一个名称中有拉丁字符的图像(
113_Atlético Madrid

我通过使用PHP函数
rawurlencode()
对其名称进行编码来保存它,因此现在它的新名称是
113_Atl%C3%A9tico%20Madrid
。但是当我试图通过这个URL打开它时,例如mysite.com/images/113_Atl%C3%A9tico%20Madrid.png我得到了404个错误

我如何解决这个问题

PHP代码:

if(isset($_FILES['Team'])){
    $avatar = $_FILES['Team'];
    $model->avatar = "{$id}_".rawurlencode($model->name).".png";
    if(!is_file(getcwd()."/images/avatars/competitions/{$model->avatar}")){
        move_uploaded_file($avatar['tmp_name']['avatar'], getcwd()."/images/avatars/teams/{$model->avatar}");
    }
}

如果您不需要保留文件名(通常有很好的理由不保留),那么最好只需完全重命名文件名。当前时间戳是一个合理的选择

if(isset($_FILES['Team'])){
    $avatar = $_FILES['Team'];
    $date = new DateTime();
    $model->avatar = "{$id}_".$date->format('Y-m-d-H-i-sP').".png";
    if(!is_file(getcwd()."/images/avatars/competitions/{$model->avatar}")){
        move_uploaded_file($avatar['tmp_name']['avatar'], getcwd()."/images/avatars/teams/{$model->avatar}");
    }
}
毕竟,文件上传前的调用不应该那么重要,更重要的是,如果两个用户有一张名为“me.png”的图片,那么发生冲突的可能性要小得多

如果您已经同意对文件名进行编码,那么我只能向您指出其他答案:


%-编码用于URL。文件名不是URL。您可以使用以下表格:

http://example.org/images/113_Atl%C3%A9tico%20Madrid.png
在URL中,web服务器将其解码为类似以下文件名:

/var/www/example-site/data/images/113_Atlético Madrid.png
当您准备将文件名放入URL时,应该使用
rawurlencode()
,但不应该使用它为光盘存储准备文件名

这里还有一个问题,即在光盘上存储非ASCII文件名是跨平台不可靠的。尤其是在Windows服务器上运行时,PHP文件API(如
move_uploaded_file()
)很可能会使用您不想要的编码,最终可能会得到类似
113_Atlético Madrid.png
的文件名

这不一定有一个简单的解决方案,但您可以使用任何形式的编码,甚至是二进制编码。因此,如果您坚持使用当前的
rawurlencode()
生成文件名:

/var/www/example-site/data/images/113_Atl%C3%A9tico%20Madrid.png
这样就可以了,但是您必须使用double-
rawurlencode
来生成匹配的URL:

http://example.org/images/113_Atl%25C3%25A9tico%2520Madrid.png
但无论如何,在文件名中包含可能由用户提供的任意字符串是非常危险的。您可能会受到目录遍历攻击,其中名称包含类似于
/../../../../
的字符串以访问目标目录之外的文件系统。(这些攻击通常会升级为针对PHP应用程序的执行任意代码攻击,这些应用程序通常是在弱权限下部署的。)您最好使用一个完全合成的名称,正如@MatthewBrown所建议的(+1)


(注意,允许用户上传文件的安全问题还没有结束,这是一项非常困难的功能。内容嗅探和插件仍然存在问题,允许将图像文件重新解释为其他类型的文件,从而导致跨站点脚本问题。为了防止所有可能的最好只从一个单独的主机名提供用户提供的文件,这样该主机上的XSS就不会让您从主站点上得到XSS。)

你需要使用
rawurldecode
:@Hackerman你能解释一下我为什么需要解码url吗?在那段代码中…你正在创建一个编码的文件名…然后你要求文件存在,如果不存在,你就在那个文件夹中创建文件,对吗?…现在你确定你检查了文件是否已上载了吗?…我想是这样的如果您不使用
rawurlencode
您的代码应该可以工作。想想看,您正在使用以下名称保存图像:
113_Atl%C3%A9tico%20Madrid.png
对吗?然后当您尝试从浏览器打开该图像时,即使文件存在,浏览器也会将其解释为:
113_Atl%C3%A9tico%20Madrid.png
d、 png,这就是它返回404错误的原因。@Hackerman当我解码它时,它的新名称变成了
113_Atlأ©tico Madrid
,而不是
113_Atlético Madrid
,有什么建议吗?这是一个很好的替代解决方案,但它会导致我更改数千张图像的名称。哎哟。我总是尝试将图像文件名存储在t所以它的名字是无关紧要的。我可以每天改变命名方法,这并不重要。