68

使用 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);
    }
    $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 接受它时遇到问题。您可以在此处查看实时副本:http: //ircb.in/jisti/ (以及我在http://ircb.in/jisti/home.html投掷的模板文件,如果您想查看的话)

知道如何解决这个问题吗?o_o

4

11 回答 11

166

您将使用以下代码删除 utf8 bom

//Remove UTF8 Bom

function remove_utf8_bom($text)
{
    $bom = pack('H*','EFBBBF');
    $text = preg_replace("/^$bom/", '', $text);
    return $text;
}
于 2013-03-15T02:55:00.910 回答
49

尝试:

// -------- read the file-content ----
$str = file_get_contents($source_file); 

// -------- remove the utf-8 BOM ----
$str = str_replace("\xEF\xBB\xBF",'',$str); 

// -------- get the Object from JSON ---- 
$obj = json_decode($str); 

:)

于 2013-09-18T11:19:03.210 回答
15

删除 BOM 的另一种方法,即 Unicode 代码点 U+FEFF

$str = preg_replace('/\x{FEFF}/u', '', $file);
于 2014-06-19T17:03:45.840 回答
8

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
...
于 2012-04-24T02:07:43.993 回答
5

如果有人使用 csv 导入,那么下面的代码很有用

$header = fgetcsv($handle);
foreach($header as $key=> $val) {
     $bom = pack('H*','EFBBBF');
     $val = preg_replace("/^$bom/", '', $val);
     $header[$key] = $val;
}
于 2018-07-18T06:10:13.320 回答
4

此全局函数解析为 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;
}
于 2016-06-22T15:13:22.137 回答
3

没有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"
于 2019-02-18T09:06:50.633 回答
2

完成相同工作的额外方法:

function remove_utf8_bom_head($text) {
    if(substr(bin2hex($text), 0, 6) === 'efbbbf') {
        $text = substr($text, 3);
    }
    return $text;
}

我发现的其他方法不适用于我的情况。

希望它在某些特殊情况下有所帮助。

于 2016-11-07T04:53:40.233 回答
1

如果您正在使用 阅读某些 APIfile_get_contents并得到一个莫名其妙NULL的 from json_decode,请检查json_last_error(): 的值有时返回的值file_get_contents会有一个无关的 BOM,当您检查字符串时几乎不可见,但会json_last_error()返回 JSON_ERROR_SYNTAX(4)。

>>> $json = file_get_contents("http://api-guiaserv.seade.gov.br/v1/orgao/all");
=> "\t{"orgao":[{"Nome":"Tribunal de Justi\u00e7a","ID_Orgao":"59","Condicao":"1"}, ...]}"
>>> json_decode($json);
=> null
>>>

在这种情况下,检查前 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",
       },
     ],
     ...
   }
于 2017-07-12T17:14:29.080 回答
1

我不太喜欢使用preg_replacepreg_match执行简单的任务。这种检测和删除 BOM 的替代方法怎么样?

function remove_utf8_bom(string $text): string
{
    $bomStart = mb_substr($text, 0, 1);
    return ($bomStart == pack('H*','EFBBBF')) ?
        mb_substr($text, 1) :
        $text;
}
于 2021-07-05T08:59:41.677 回答
0

当使用有缺陷的软件时,BOM 部分会随着每次节省而成倍增加。

所以我用它来摆脱它。

function remove_utf8_bom($text) {
    $bom = pack('H*','EFBBBF');
    while (preg_match("/^$bom/", $text)) {
        $text = preg_replace("/^$bom/", '', $text);
    }
    return $text;
}
于 2019-06-09T08:49:02.670 回答