【问题标题】:How to remove %EF%BB%BF in a PHP string如何删除 PHP 字符串中的 %EF%BB%BF
【发布时间】:2010-10-30 07:37:06
【问题描述】:

我正在尝试使用 Microsoft Bing API。

$data = file_get_contents("http://api.microsofttranslator.com/V2/Ajax.svc/Speak?appId=APPID&text={$text}&language=ja&format=audio/wav");
$data = stripslashes(trim($data));

返回的数据在返回字符串的第一个字符中有一个''字符。它不是空格,因为我在返回数据之前对其进行了修剪。

' ' 字符原来是 %EF%BB%BF。

我想知道为什么会这样,也许是微软的错误?

如何在 PHP 中删除这个 %EF%BB%BF?

【问题讨论】:

    标签: php bing-api microsoft-translator


    【解决方案1】:

    除非您 100% 确定流将:(a) 始终为 UTF-8,并且 (b) 始终具有 UTF-8 BOM,否则不应简单地丢弃 BOM。

    原因:

    1. 在 UTF-8 中,BOM 是可选的 - 因此,如果服务在未来某个时间点停止发送它,您将丢弃响应的前三个字符。
    2. BOM 的全部目的是明确识别被解释为 UTF-8 的 UTF 流的类型? -16?或 -32?,并且还表示编码信息的“字节序”(字节顺序)。如果你只是把它扔掉,你会假设你总是得到 UTF-8;这可能不是一个很好的假设。
    3. 并非所有 BOM 都是 3 字节长,只有 UTF-8 是 3 字节。 UTF-16 是两个字节,UTF-32 是四个字节。因此,如果将来该服务切换到更广泛的 UTF 编码,您的代码将会中断。

    我认为更合适的处理方式是:

    /* Detect the encoding, then convert from detected encoding to ASCII */
    $enc = mb_detect_encoding($data);
    $data = mb_convert_encoding($data, "ASCII", $enc);
    

    【讨论】:

    • 这在实践中似乎行不通。 mb_convert_encoding("\357\273\277some text", 'ASCII', mb_detect_encoding("\357\273\277some text")) 产生 string(10) "?some text"。请注意,它在输出中留下了一个问号。
    • @mark 不幸的是,这似乎是真的。我最好使用iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE',"\357\273\277some text") 进行转换。我猜mb_detect_encoding 将用于检测初始字符集,然后将其作为第一个参数传递给iconv。这更像是一种黑客行为。
    • @mark 我必须添加以下行来摆脱 ? : ini_set('mbstring.substitute_character', "none");
    【解决方案2】:

    $data = file_get_contents("http://api.microsofttranslator.com/V2/Ajax.svc/Speak?appId=APPID&text={$text}&language=ja&format=audio/wav");
    $data = stripslashes(trim($data));

    if (substr($data, 0, 3) == "\xef\xbb\xbf") {
    $data = substr($data, 3);
    }

    【讨论】:

    • 这个解决方案很棒!当我找不到答案时,它帮助了我很多。最好的逻辑部分是创建一个条件,如果 BOM Hex Charakters 存在,然后删除它们。此代码似乎将来保存,即使服务器不发送 BOM,此功能仍然有效。 +1
    【解决方案3】:

    这是一个byte order mark (BOM),表示响应编码为UTF-8。您可以安全地删除它,但您应该将其余部分解析为 UTF-8。

    【讨论】:

      【解决方案4】:

      我今天遇到了同样的问题,并通过确保将字符串设置为 UTF-8 来解决:

      http://php.net/manual/en/function.utf8-encode.php

      $content = utf8_encode ($content);

      【讨论】:

        【解决方案5】:

        从字符串的开头删除它(仅):

        $data = preg_replace('/^%EF%BB%BF/', '', $data);
        

        【讨论】:

          【解决方案6】:

          $data = str_replace('%EF%BB%BF', '', $data);

          您可能不应该使用 stripslashes —— 除非 API 返回带有黑色斜线的数据(并且有 99.99% 的可能性不会),否则请取消该调用。

          【讨论】:

            【解决方案7】:

            您可以使用substr 只获取其余部分,而不使用UTF-8 BOM

            // if it’s binary UTF-8
            $data = substr($data, 3);
            // if it’s percent-encoded UTF-8
            $data = substr($data, 9);
            

            【讨论】:

            • 注意:一般来说,丢弃 BOM 并不是一个好主意。 BOM 会告诉您应该如何处理字符串的其余部分。如果您只是忽略它,假设它是一个 UTF-8 3 字节 BOM,那么如果/当编码发生变化时,您将面临一些真正的问题。 ...请在下面查看我的答案以获取更多详细信息。
            • 致未来的谷歌员工:use this solution instead。丢弃 BOM 是一个坏主意
            猜你喜欢
            • 2020-07-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多