奇怪的字符编码问题导致js函数失败或添加不需要的字符

时间:2012-01-04 09:32:59

标签: php javascript encoding character-encoding

我正在编写的PHP函数使用file_get_contents()从另一个网页中提取一小部分HTML数据,然后解析出一段文本并尝试将其存储在数据库中。问题是,它得到的数据必须用不同的字符集或其他东西编码(我不肯定如何检查这个)因为它经常添加(在字符串中看似随机的地方,并不总是在开头或结尾并且每隔一段时间就会添加一条我不想要的新线。 很烦人但是当添加换行符时会导致javascript函数失败。 javascript函数从php脚本打印如下:

print <<<END
    setUpSend("${a}", "${b}", "${c}", "${d}");
END;

当输入换行符时,该函数不再有效(我想是因为换行符),并且查看源代码显示如下:

print <<<END
        setUpSend("a information", "b information
", "c information", "d information");
END;

我做了一些研究,发现这个是UTF-8 BOM(字节顺序标记),建议将信息解析为xml而不是字符串 - 我发现有一些php库要做这个(http://php.net/manual/en/book.xml.php)但是想到可能有一种更简单的方法,比如一个简单的PHP函数,它会自动转换它,或者删除不需要的字符。

此外,有时信息可以包含引号,但由于这也会搞乱js函数,我试图使用PHP的addslashes函数,它只是不添加任何斜杠,根本不工作。但是,如果我手动在php中写相同的字符串,并使用addslashes,它会正常添加斜杠,所以它让我觉得不知道php不能理解我得到的这个文本的编码。奇怪的事情正在发生,但我迷失了如何解决它。

我对任何建议都持开放态度,因为我已经查了很多东西,但无法找到解决这个问题的好方法。

1 个答案:

答案 0 :(得分:4)

可能是UTF-8 encoded BOM。如果您知道源编码是UTF-8,则通常可以安全地删除它。

这是一个简单的字符串操作:

$withOutUTF8BOM = remove_UTF8BOM($withOrWithOutUTF8BOM);


/**
 * Remove UTF8BOM from the beginning of a string (if it exists)
 *
 * @return string
 */
function remove_UTF8BOM($str)
{
    $UTF8BOM = "\xEF\xBB\xBF";
    (0 === strpos($str, $UTF8BOM)) && $str = (string) substr($str, 3);
    return $str;
}

但是,您应该知道您的代码输入编码。 HTML数据可以采用不同的编码,因此可能需要预先规范化HTML编码(例如,将所有非UTF-8字符集转换为UTF-8),然后使自己的函数正确处理UTF-8编码数据。

  

我正在编写的PHP函数使用file_get_contents()从另一个网页中提取一小部分HTML数据,然后解析一段文本并尝试将其存储在数据库中。问题是,它得到的数据必须用不同的字符集或其他东西编码(我不肯定如何检查)

使用file_get_contents检索数据后,您可以获取响应标头。这些存储在$http_response_header中。以下示例演示了这一点 (parse_http_response_header函数见HEAD first with PHP Streams):

$url = 'http://example.com/';

$body = file_get_contents($url);

$responses = parse_http_response_header($http_response_header);

$contentType = $responses[0]['fields']['CONTENT-TYPE']; // CONTENT-TYPE

echo "Content-Type: $contentType\n";  # Content-Type: text/html; charset=UTF-8

您只需检查该标题行是否存在以及是否指定了字符集。请参阅Content-Type­RFC 2616标头规范如何编写:

list($typeAndSubType, $parameter) = explode(';' $contentType, 2) + array(NULL,NULL);

如果有no media-type given (type and sub-type),您可以(但绝不能)尝试猜测它。当您处理HTML时,通常是text/html

   Content-Type   = "Content-Type" ":" media-type

   media-type     = type "/" subtype *( ";" parameter )
   type           = token
   subtype        = token

如果没有给出charset参数,请使用该类型的默认字符集(text)。在HTTP中,这是ISO‑8859ref)。

要正确解析参数,请参阅Section 3.6

   parameter               = attribute "=" value
   attribute               = token
   value                   = token | quoted-string

要正确解析我作为练习留下的参数字符串。