Php 如何删除多个UTF-8 BOM序列
使用PHP5(cgi)从文件系统输出模板文件,并在输出原始HTML时遇到问题Php 如何删除多个UTF-8 BOM序列,php,utf-8,byte-order-mark,Php,Utf 8,Byte Order Mark,使用PHP5(cgi)从文件系统输出模板文件,并在输出原始HTML时遇到问题 private function fetch($name) { $path = $this->j->config['template_path'] . $name . '.html'; if (!file_exists($path)) { dbgerror('Could not find the template "' . $name . '" in ' . $path);
private function fetch($name) {
$path = $this->j->config['template_path'] . $name . '.html';
if (!file_exists($path)) {
dbgerror('Could not find the template "' . $name . '" in ' . $path);
}
$f = fopen($path, 'r');
$t = fread($f, filesize($path));
fclose($f);
if (substr($t, 0, 3) == b'\xef\xbb\xbf') {
$t = substr($t, 3);
}
return $t;
}
尽管我已经添加了BOM修复,但Firefox接受它时仍然存在问题。你可以在这里看到一个实时副本:(如果你想查看的话,还有我抛出的模板文件)
你知道怎么解决这个问题吗?o_o
b'\xef\xbb\xbf'
代表文本字符串“\xef\xbb\xbf”。如果要检查BOM表,则需要使用双引号,以便将\x
序列实际解释为字节:
"\xef\xbb\xbf"
您的文件似乎也包含了比单个前导BOM表多得多的垃圾:
$ curl http://ircb.in/jisti/ | xxd
0000000: efbb bfef bbbf efbb bfef bbbf efbb bfef ................
0000010: bbbf efbb bf3c 2144 4f43 5459 5045 2068 .....<!DOCTYPE h
0000020: 746d 6c3e 0a3c 6874 6d6c 3e0a 3c68 6561 tml>.<html>.<hea
...
$curlhttp://ircb.in/jisti/ |xxd
0000000:efbb bfef bbbf efbb bfef bbbf efbb bfef。。。。。。。。。。。。。。。。
0000010:bbbf efbb bf3c 2144 4f43 5459 5045 2068……您将使用以下代码删除utf8 bom
//Remove UTF8 Bom
function remove_utf8_bom($text)
{
$bom = pack('H*','EFBBBF');
$text = preg_replace("/^$bom/", '', $text);
return $text;
}
尝试:
:)删除BOM的另一种方法是Unicode代码点U+FEFF
$str = preg_replace('/\x{FEFF}/u', '', $file);
这是UTF-8系统基字符集的全局函数解析。坦克
function prepareCharset($str) {
// set default encode
mb_internal_encoding('UTF-8');
// pre filter
if (empty($str)) {
return $str;
}
// get charset
$charset = mb_detect_encoding($str, array('ISO-8859-1', 'UTF-8', 'ASCII'));
if (stristr($charset, 'utf') || stristr($charset, 'iso')) {
$str = iconv('ISO-8859-1', 'UTF-8//TRANSLIT', utf8_decode($str));
} else {
$str = mb_convert_encoding($str, 'UTF-8', 'UTF-8');
}
// remove BOM
$str = urldecode(str_replace("%C2%81", '', urlencode($str)));
// prepare string
return $str;
}
完成相同工作的额外方法:
function remove_utf8_bom_head($text) {
if(substr(bin2hex($text), 0, 6) === 'efbbbf') {
$text = substr($text, 3);
}
return $text;
}
我发现的其他方法在我的情况下不起作用
希望在某些特殊情况下有所帮助。如果您正在使用文件获取内容阅读一些API,并且从json\u decode
中获取了一个无法解释的NULL
,请检查json\u last\u error()的值
:有时从文件\u get\u contents
返回的值会有一个无关的BOM表,当您检查字符串时,它几乎不可见,但会使json\u last\u error()
返回json\u error\u语法
(4)
在这种情况下,请检查前3个字节-回显它们不是很有用,因为BOM表在大多数设置中是不可见的:
>>> substr($json, 0, 3)
=> " "
>>> substr($json, 0, 3) == pack('H*','EFBBBF');
=> true
>>>
如果上面的行对您来说返回TRUE,那么一个简单的测试可能会解决问题:
>>> json_decode($json[0] == "{" ? $json : substr($json, 3))
=> {#204
+"orgao": [
{#203
+"Nome": "Tribunal de Justiça",
+"ID_Orgao": "59",
+"Condicao": "1",
},
],
...
}
这可能会有帮助。如果你想让我扩展我的思维过程,请告诉我
<?php
//
// labled TESTINGSTRIPZ.php
//
define('CHARSET', 'UTF-8');
$stringy = "\xef\xbb\xbf\"quoted text\" ";
$str_find_array = array( "\xef\xbb\xbf");
$str_replace_array = array( '');
$RESULT =
trim(
mb_convert_encoding(
str_replace(
$str_find_array,
$str_replace_array,
strip_tags( $stringy )
),
'UTF-8',
mb_detect_encoding(
strip_tags($stringy)
)
)
);
print("YOUR RESULT IS: " . $RESULT.PHP_EOL);
?>
结果:
terminal$ php TESTINGSTRIPZ.php
YOUR RESULT IS: "quoted text" // < with no hidden char.
terminal$php TESTINGSTRIPZ.php
您的结果是:“引用的文本”//<,没有隐藏字符。
如果有人使用csv导入,那么下面的代码很有用
$header = fgetcsv($handle);
foreach($header as $key=> $val) {
$bom = pack('H*','EFBBBF');
$val = preg_replace("/^$bom/", '', $val);
$header[$key] = $val;
}
不带pack
功能的解决方案:
$a = "1";
var_dump($a); // string(4) "1"
function deleteBom($text)
{
return preg_replace("/^\xEF\xBB\xBF/", '', $text);
}
var_dump(deleteBom($a)); // string(1) "1"
使用有故障的软件时,每次保存时BOM表零件都会成倍增加
所以我用这个来摆脱它
function remove_utf8_bom($text) {
$bom = pack('H*','EFBBBF');
while (preg_match("/^$bom/", $text)) {
$text = preg_replace("/^$bom/", '', $text);
}
return $text;
}
utf8文件不应该有一个BOM表,如果你的编辑器把它们放进去,应该有一个省略这些的配置,如果你的编辑器不允许你不放进BOM表,替换你的编辑器。是的。我使用n++,我尝试不使用BOMif。如果我使用n++,为什么会出现这种情况?它将它保存为unix/utf8-BOM将它保存为UTF-8无BOM(或N++中的任何名称)。我这样做了,但仍然得到相同的结果。我对直接文件(curl | xxd)进行了卷曲,没有前导字符,但是卷曲PHP脚本会在前面添加多余的数据,我使用的只是打印输出数据。这一个为我解决了问题,感谢发布此解决方案!通常是比较容易的。:-)出于某种原因,在Google+API中,这个BOM显示在内容变量的末尾,因此我需要调整它以将其从字符串的末尾删除。有人能解释一下这里是如何使用pack函数的吗?我知道它会将字符串转换为二进制表示形式,但很难理解这如何有助于识别BOM Unicode字符。这对于我从SSR读取CSV输出并附加到更大文件的要求非常有用。最后,一种BOM转义技术确实有效,谢谢@fsociety BOM是三个字节-0xef 0xbb 0xbf
。所以pack使用的是H*格式,这意味着将字符串中的所有值解释为十六进制字节。我更喜欢o1max的答案(尽管分数较低),它只使用带转义字符的字符串:“\xEF\xBB\xBF”
如果它们可以出现多次,您可能需要使用“/^(\xEF\xBB\xBF)+/”
$a = "1";
var_dump($a); // string(4) "1"
function deleteBom($text)
{
return preg_replace("/^\xEF\xBB\xBF/", '', $text);
}
var_dump(deleteBom($a)); // string(1) "1"
function remove_utf8_bom($text) {
$bom = pack('H*','EFBBBF');
while (preg_match("/^$bom/", $text)) {
$text = preg_replace("/^$bom/", '', $text);
}
return $text;
}