PHP:RFC-2231 如何将 UTF-8 字符串编码为 Content-Disposition 文件名

Posted

技术标签:

【中文标题】PHP:RFC-2231 如何将 UTF-8 字符串编码为 Content-Disposition 文件名【英文标题】:PHP: RFC-2231 How to encode UTF-8 String as Content-Disposition filename 【发布时间】:2011-04-20 20:37:34 【问题描述】:

场景:(在 php 中)我有一个带有 UTF-8 编码字符串 ($name) 的表单提交,以支持国际字符。提交表单(通过 GET)后,我正在创建一个 CSV 下载文件。我希望文件的名称是 string + .csv ("$name.csv")。对于西方字符集,我可以这样做:

header("Content-Disposition: attachment; filename=\"$name\"");

但对于其他字符集,下载文件的名称是垃圾字母 + .csv(如×œ×œ× ×›×•×ª×¨×ª.csv)。我正在尝试按照 RFC 2231 执行以下操作:

header("Content-Disposition: attachment; filename*=UTF-8''$name");

但我似乎有几个问题:

    浏览器似乎忽略了标题的“文件名”部分。我的格式对吗?

    我需要将$name 八位字节的每个字符编码为十六进制,例如“This%20is%20%2A%2A%2Afun%2A%2A%2A”。有没有人有正确执行此操作的功能?我编写了以下代码,但我认为它不正确:

    $fileName = encodeWordRfc2231($name) . ".csv";
    header("Content-Disposition: attachment; filename*=UTF-8''$fileName");
    
    function &encodeWordRfc2231($word) 
        $binArray = unpack("C*", $word);
        foreach ($binArray as $chr) 
            $hex_ary[] = '%' . sprintf("%02X", base_convert($chr, 2, 16));
        
        return implode('', $hex_ary);
    
    

有没有人有这方面的经验,可以让我走上正确的道路?

【问题讨论】:

PHP 在内部使用字符串构建器来处理字符串,因此无需将字符串片段存储在 $hex_ary 中。您应该只使用 $hex = ''; 然后将每个部分附加到它。 见***.com/questions/4968272/… 【参考方案1】:

使用rawurlencode()根据RFC 3986对文件名进行编码就足够了

所以您需要做的就是将 header() 行更改为:

header("Content-Disposition: attachment; filename*=UTF-8''".rawurlencode($name));

直接回答问题:

    格式正确,但是$name里面的文字需要用rawurlencode()编码。 rawurlencode() 成功了。

【讨论】:

以上是关于PHP:RFC-2231 如何将 UTF-8 字符串编码为 Content-Disposition 文件名的主要内容,如果未能解决你的问题,请参考以下文章

如何根据 RFC 2231 在 PHP 中对文件名进行编码?

php - 如何将 unicode 转换为 utf-8 字符串

如何使JSONObject的toString()将UTF-8字符编码为unicode,就像在PHP的json_encode中一样?

如何将 latin1 字符集关联数组从 php 传递到 javascript?

如何使用 PHP 列出不属于 ISO 8859-1 字符集的文本文件中使用的所有 UTF-8 字符?

PHP 将格式错误的UTF-8 HTML转换为正确格式的UTF-8纯文本字符串。