0

我最近和朋友一起完成的一个网站有一个画廊,可以上传图片和文本文件。唯一接受的文本文件(以简化开发)是 .txt 并且通常会顺利关闭(或没有..)

我遇到的问题对于任何开发人员都是一样的:Microsoft 的扩展 ASCII。

在从文件中输出文本之前,我检查了几个不同的层以尝试清理它:

$txtfile = file_get_contents(".".$this->var['submission']['file_loc']);

// BOM Fun
    $boms = array
    (
        "utf8"    => array(3,pack("CCC",0xEF,0xBB,0xBF)),
        "utf16be"       => array(2,pack("CC",0xFE,0xFF)),
        "utf16le"       => array(2,pack("CC",0xFF,0xFE)),
        "utf32be"       => array(4,pack("CCCC",0x00,0x00,0xFE,0xFF)),
        "utf32le"       => array(4,pack("CCCC",0xFF,0xFE,0x00,0x00)),
        "gb18030"       => array(4,pack("CCCC",0x84,0x31,0x95,0x33))
    );
    foreach($boms as $bom)
    {
        if(mb_substr($txtfile,0,$bom[0]) == $bom[1])
        {
            $txtfile = substr($txtfile,$bom[0]);
            break;
        }
    }
$txtfile_o = $txtfile;
$badwords = array(chr(145),chr(146),chr(147),chr(148),chr(151),chr(133));
$fixwords = array("'","'",'"','"','-','...');
$txtfile_o = str_replace($badwords,$fixwords,$txtfile_o);
$txtfile_o = mb_convert_encoding($txtfile_o,"UTF-8");

str_replace 是将 Microsoft 糟糕的智能引号、em-dash 和省略号转换为正常的 ASCII 等效项以进行输出的通用方法。

此代码在上传的文件为 ANSI/us-ascii 的情况下完美运行。

当上传的文件为 UTF-8 时,此代码不起作用(无特殊原因)。

当文件为 UTF-8 时,在 Web 浏览器中查看文件本身可以正常工作,但使用此代码通过 Web 界面将其打印出来则不行。在这种情况下,智能引号成为某种重音字符。

这就是我卡住的地方。网页的输出编码为 UTF-8,Web 浏览器将其视为 UTF-8,文件为 UTF-8,但智能引号的替换不起作用,Web 浏览器也无法正确显示它们。

对此的任何和所有帮助将不胜感激。

4

2 回答 2

1

如果我理解正确,您的问题是当用户以 UTF-8 提交文件时,您的 ASCII 对应字符替换“扩展 ASCII”字符的代码会失败。

这是意料之中的。不能对 UTF-8 文件进行str_replace操作,它们是在字节级别操作的,而 UTF-8 中的字符仅由 ASCII 范围内的字符构成的一个字节。

我建议您做的是使用一些启发式方法来确定文件是否以 UTF-8 编码(如果您确定它会存在,BOM 是一个好方法)或 Windows-1252 或其他什么然后如果不是,请将其转换为 UTF-8。在这种情况下,您不需要替换任何字符,您可以保留智能引号。

于 2010-06-19T16:42:34.610 回答
0

您尝试替换的字符在 UTF8 中具有不同的字节值。实际上,它们在 UTF8 中每个都有一个以上的字节。您正在尝试使用 Windows 编码值搜索它们,这就是您找不到它们的原因。

查找字符的 UTF8 字节序列并将其用于搜索。

于 2010-06-19T16:29:34.377 回答