在文件上传中处理扩展的ASCII
-
28-09-2019 - |
题
我最近与朋友一起完成的网站有一个画廊,可以在其中上传图像和文本文件。唯一接受的文本文件(以简化开发)是.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和Ellipsis转换为其正常的ASCII等效物以进行输出的一般方法。
该代码在上传的文件是ANSI / US-ASCII的条件下完美地找到。
当上传文件为UTF-8时,此代码(无特定原因)不起作用。
当文件为UTF-8时,在Web浏览器中查看文件本身工作正常,但是使用此代码通过Web界面将其打印出来。在这种情况下,智能引号变成了某种角色。
这就是我卡住的地方。该网页的输出编码为UTF-8,Web浏览器将其视为UTF-8,该文件在UTF-8中,但SMART引号的替换均无法正常工作,也不适用于Web浏览器。
所有方面的帮助将不胜感激。
解决方案
如果我正确理解您的问题是,当用户在UTF-8中提交文件时,您的ASCII对应物替换“扩展ASCII”字符的代码失败。
这是可以预料的。您无法使用UTF-8文件操作 str_replace
和在字节级别运行的类似,而UTF-8中的字符仅由一个字节仅针对ASCII范围内的字符构成。
我建议您要做的是使用一些启发式方法来确定文件是否在UTF-8中编码(如果您确定会在场的话,BOM是一种好方法)或Windows-1252或其他任何内容如果不是,则将其转换为UTF-8。在这种情况下,您无需更换任何字符,就可以保留智能报价。
其他提示
您要替换的字符在UTF8中具有不同的字节值。实际上,它们在UTF8中的每个字节都以上。您正在尝试使用Windows编码值搜索它们,这就是为什么您找不到它们。
查找字符的UTF8字节序列,并将其用于搜索。