如何删除多个UTF-8 BOM序列

时间:2012-04-24 02:04:55

标签: 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);
    }
    $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

12 个答案:

答案 0 :(得分:126)

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

//Remove UTF8 Bom

function remove_utf8_bom($text)
{
    $bom = pack('H*','EFBBBF');
    $text = preg_replace("/^$bom/", '', $text);
    return $text;
}

答案 1 :(得分:32)

尝试:

// -------- 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); 

:)

答案 2 :(得分:10)

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

$str = preg_replace('/\x{FEFF}/u', '', $file);

答案 3 :(得分:7)

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
...

答案 4 :(得分: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;
}

答案 5 :(得分:2)

如果有人使用csv import,则下面的代码有用

           $header = fgetcsv($handle);
            foreach($header as $key=> $val) {
                $bom = pack('H*','EFBBBF');
                $val = preg_replace("/^$bom/", '', $val);
                $header[$key] = $val;
            }

答案 6 :(得分:1)

执行相同工作的额外方法:

<div class="section"> 
  <div class="container-fluid">
    <div class="row">
      <div class="col-sm-6"><div class="embed-responsive embed-responsive-16by9"> 

        <img  class="embed-responsive-item" width="600px" height="360" src="images\phone.jpg"/>                                  </div>
      </div>
      <div class="col-sm-6">
        <div class="embed-responsive embed-responsive-16by9"><iframe width="560" height="315" class="embed-responsive-item" src="https://www.youtube.com/embed/_k4SA"></iframe>
        </div>
      </div>
    </div>
  </div>
</div>

我找到的其他方法在我的情况下无效。

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

答案 7 :(得分:1)

如果您正在使用file_get_contents阅读某些API并从NULL获得一个无法解释的json_decode,请检查json_last_error()的值:有时从{{1}返回的值在检查字符串时,将会有一个几乎不可见的无关BOM,但会使file_get_contents返回json_last_error()(4)。

JSON_ERROR_SYNTAX

在这种情况下,检查前3个字节 - 回显它们不是很有用,因为在大多数设置中BOM都是不可见的:

>>> $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
>>>

如果上面的行为您返回TRUE,那么一个简单的测试可以解决问题:

>>> substr($json, 0, 3)
=> "  "
>>> substr($json, 0, 3) == pack('H*','EFBBBF');
=> true
>>>

答案 8 :(得分:0)

这可能会有所帮助。如果你关心我扩展我的思维过程,请告诉我。

<?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.

答案 9 :(得分:0)

没有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"

答案 10 :(得分:0)

使用错误的软件时,每次保存都会使BOM零件成倍增加。

所以我正在用它摆脱它。

function remove_utf8_bom($text) {
$bom = pack('H*','EFBBBF');
while (preg_match("/^$bom/", $text)) {
    $text = preg_replace("/^$bom/", '', $text);
}
return $text;

}

答案 11 :(得分:0)

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

function remove_utf8_bom(string $text): string
{
    $bomStart = mb_substr($text, 0, 1);
    return ($bomStart == pack('H*','EFBBBF')) ?
        mb_substr($data, 1) :
        $text;
}