3

我正在尝试使用 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?

4

7 回答 7

17

除非您 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);
于 2010-10-30T08:21:00.703 回答
5

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

于 2013-08-13T20:54:49.537 回答
2

它是一个字节顺序标记(BOM),表示响应编码为UTF-8。您可以安全地删除它,但您应该将其余部分解析为 UTF-8。

于 2010-10-30T07:42:07.390 回答
0

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

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

$content = utf8_encode ( $content );

于 2013-07-09T20:54:43.087 回答
-1

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

$data = preg_replace('/^%EF%BB%BF/', '', $data);
于 2010-10-30T07:40:43.030 回答
-1

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

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

于 2010-10-30T07:42:53.623 回答
-3

您可以使用仅在没有UTF-8 BOMsubstr的情况下获取其余部分:

// if it’s binary UTF-8
$data = substr($data, 3);
// if it’s percent-encoded UTF-8
$data = substr($data, 9);
于 2010-10-30T07:42:07.373 回答