处理文件上载中的扩展ASCII

时间:2010-06-19 16:19:47

标签: php utf-8 file-upload extended-ascii smart-quotes

我最近与朋友完成的网站有一个图库,可以上传图片和文本文件。唯一可接受的文本文件(为了便于开发)是.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浏览器也无法正确显示。

非常感谢任何和所有这方面的帮助。

2 个答案:

答案 0 :(得分:1)

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

这是可以预料的。您不能使用str_replace等在字节级操作的UTF-8文件,而UTF-8中的字符仅由ASCII范围内的字符构成一个字节。

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

答案 1 :(得分:0)

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

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