2012-04-24 27 views
39

Sử dụng PHP5 (cgi) để xuất tệp mẫu từ hệ thống tệp và gặp sự cố khi loại bỏ HTML thô.Làm thế nào để loại bỏ nhiều chuỗi UTF-8 BOM trước "<!DOCTYPE>"?

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; 
} 

Mặc dù tôi đã thêm bản sửa lỗi BOM Tôi vẫn gặp sự cố khi Firefox chấp nhận. Bạn có thể xem bản sao trực tiếp tại đây: http://ircb.in/jisti/ (và tệp mẫu tôi đã ném tại http://ircb.in/jisti/home.html nếu bạn muốn kiểm tra)

Bất kỳ ý tưởng nào để khắc phục sự cố này? o_o

+7

tập tin utf8 không nên có một BOM, nếu soạn thảo của bạn đưa những người trong, cần có một cấu hình để bỏ qua những, nếu soạn thảo của bạn sẽ không cho phép bạn không đặt trong BOM, thay thế trình soạn thảo của bạn. –

+0

vâng. Tôi sử dụng n + +, và tôi đã thử mà không có BOM – sheppardzw

Trả lời

93

bạn sẽ sử dụng đoạn mã sau để loại bỏ utf8 bom

//Remove UTF8 Bom 

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

Điều này làm việc cho tôi. –

+0

Đã thử nhiều giải pháp, nhưng giải pháp này đã hoạt động. Cảm ơn! – nijlgier

+0

Vì một số lý do trong API Google+, BOM này hiển thị ở cuối biến nội dung, vì vậy tôi cần phải tinh chỉnh điều này để xóa nó khỏi cuối chuỗi. –

4

b'\xef\xbb\xbf' là viết tắt của chuỗi chữ "\ xef \ xbb \ xbf". Nếu bạn muốn kiểm tra cho một BOM, bạn cần phải sử dụng dấu ngoặc kép, vì vậy \x chuỗi được thực sự giải thích vào byte:

"\xef\xbb\xbf" 

file của bạn cũng dường như chứa rác nhiều hơn chỉ là một BOM hàng đầu duy nhất:

$ 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 
... 
+0

nếu tôi đã sử dụng n + +, tại sao nó sẽ gây ra điều này? nó lưu nó dưới dạng unix/utf8 -bom – sheppardzw

+0

Lưu nó dưới dạng UTF-8 NO BOM (hoặc bất kỳ thứ gì được gọi trong N ++). – deceze

+0

Tôi đã làm và tôi vẫn nhận được kết quả tương tự. Tôi curl'd các tập tin trực tiếp (curl http://ircb.in/jisti/home.html | xxd) và không có nhân vật hàng đầu, nhưng curl'ing kịch bản PHP thêm dữ liệu dư thừa ở phía trước và tất cả tôi sử dụng là in để xuất dữ liệu. – sheppardzw

25

thử:

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

:)

+0

Điều này đã làm một thủ thuật cho tôi, cảm ơn bạn đã đăng giải pháp này! – Blaater

+0

Thường thì dễ hơn. :-) – Bondt

6

Một cách khác để loại bỏ các BOM đó là mã Unicode điểm U + FEFF

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

này quyết tâm Chức năng toàn cầu cho charset UTF-8 hệ thống cơ sở. Xe tăng!

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; 
} 
1

Một phương pháp bổ sung để thực hiện công việc tương tự:

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

Các phương pháp khác tôi thấy không thể làm việc trong trường hợp của tôi.

Hy vọng nó sẽ giúp ích trong một số trường hợp đặc biệt.

1

Nếu bạn đang đọc một số API sử dụng file_get_contents và có một không thể giải thích NULL từ json_decode, kiểm tra giá trị của json_last_error(): đôi khi giá trị trả về từ file_get_contents sẽ có một BOM không liên quan đó là gần như vô hình khi bạn kiểm tra chuỗi, nhưng sẽ làm cho json_last_error() để trả lại 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 
>>> 

Trong trường hợp này, đánh dấu vào 3 byte đầu tiên - lặp lại họ không phải là rất hữu ích vì BOM là vô hình trên hầu hết các thiết lập:

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

Nếu dòng trên lợi nhuận TRUE cho bạn, sau đó một thử nghiệm đơn giản có thể khắc phục sự cố:

>>> json_decode($json[0] == "{" ? $json : substr($json, 3)) 
=> {#204 
    +"orgao": [ 
     {#203 
     +"Nome": "Tribunal de Justiça", 
     +"ID_Orgao": "59", 
     +"Condicao": "1", 
     }, 
    ], 
    ... 
    } 
0

Điều này có thể hữu ích. cho tôi biết nếu bạn chăm sóc cho tôi để mở rộng quá trình suy nghĩ của tôi.

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

?> 

Kết quả:

terminal$ php TESTINGSTRIPZ.php 
     YOUR RESULT IS: "quoted text" // < with no hidden char. 
Các vấn đề liên quan