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

时间:2010-10-04 14:49:15

标签: php content-disposition rfc2231

场景:(在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");

但我似乎有几个问题:

  1. 浏览器似乎忽略了标题的“ filename ”部分。我的格式是对的吗?
  2. 我需要编码以十六进制编码的$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);
    }
    
  3. 有没有人有这方面的经验,可以让我走上正确的道路?

1 个答案:

答案 0 :(得分:6)

使用RFC 3986

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

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

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

直接回答问题:

  1. 格式正确,但$ name中的文字需要使用rawurlencode()进行编码。
  2. rawurlencode()可以解决问题。