【问题标题】:PHP simplexml_load_file with special chars in URLURL 中带有特殊字符的 PHP simplexml_load_file
【发布时间】:2012-02-15 02:19:37
【问题描述】:

我正在尝试根据用户的 IP 检索当地天气预报。

我正在使用 geoplugin.net 获取用户位置并将城市和国家/地区名称提供给 Google Weather API。

//Get user IP
$ip = $_SERVER['REMOTE_ADDR'];

$geolocation = unserialize(file_get_contents('http://www.geoplugin.net/php.gp?ip='.$ip));
$geo_city = $geolocation['geoplugin_city'];
$geo_country = $geolocation['geoplugin_countryName'];

$file = "http://www.google.com/ig/api?weather=".$geo_city.",".$geo_country;
$xml = simplexml_load_file($file);

//Echo content of retrieved XML for debugging purposes
echo "<pre>";
print_r($xml);
echo "</pre>";

它适用于大多数情况,但是当我在自己的 IP 上尝试它时,我得到了丹麦的 Søborg(它不是 100% 准确,但足够接近),这给了我来自天气 API 的几乎空洞的响应。

此案的主要嫌疑人是卑鄙的“ø”字。

我想要的 XML 可以在这里看到:http://www.google.com/ig/api?weather=S%C3%B8borg,Denmark

我得到的 XML 可以在这里看到:http://www.google.com/ig/api?weather=S

当我在浏览器中输入这个 URL 时,它可以正常工作:

http://www.google.com/ig/api?weather=Søborg,Denmark

当我使用这个版本时,它也能正常工作(在浏览器中):

http://www.google.com/ig/api?weather=S%C3%B8borg,Denmark

但此版本返回 Borg,Syddanmark 的预测:

http://www.google.com/ig/api?weather=S%26oslash%3Bborg,Denmark

当馈送到 simplexml_load_file() 时,以上都不会返回所需的结果。

如上所述,我怀疑这是字符集问题,但我不知道该怎么办。

正确的解决方法是什么?

我知道我可以使用纬度和经度作为 Google Weather API 的参数,但这只是规避问题,而不是解决问题。

【问题讨论】:

    标签: php url character-encoding


    【解决方案1】:

    听起来确实像字符集问题。您是否尝试过将 URL 转换为另一种编码,例如在将结果传递给simplexml_load_file()之前使用iconv

    【讨论】:

    • 不太清楚我在转换什么。我已经尝试了iconv("ISO-8859-1", "UTF-8", $file) 和其他方法,但都没有成功。 utf8_encode($file) 也没有结果。
    【解决方案2】:

    试试这个:

    $file = "http://www.google.com/ig/api?weather=" . $geo_city . "," . $geo_country;
    $data = file_get_contents($file);
    $data = mb_convert_encoding($data, "UTF-8", "ISO-8859-2");
    
    $xml = simplexml_load_string($data);
    echo "<pre>"; print_r($xml); echo "</pre>";
    

    取自可能类似的帖子:https://stackoverflow.com/a/5136549/949476

    【讨论】:

    • 响应仍然是空的,就像使用此 url 调用服务一样:http://www.google.com/ig/api?weather=s
    • 如果你只运行这段代码$data = file_get_contents("http://www.google.com/ig/api?weather=Søborg,Denmark");响应也是空的?
    • 是的,空的意思和上面一样。我确实得到了 一些 xml,但其中没有预测数据。
    【解决方案3】:

    如果您对 S%26oslash%3Bborg 进行 URL 解码,您会看到该字符串对应于 S&amp;oslash;borg,在我们像这样解码 HTML 实体后,这给了我们 Søborg

    $city = 'S%26oslash%3Bborg,Denmark';
    echo $city = rawurldecode($city);
    //prints S&oslash;borg,Denmark
    
    echo $city = html_entity_decode($city, 0, 'UTF-8');
    //prints Søborg,Denmark
    
    echo $city = rawurlencode($city);
    //prints S%C3%B8borg%2CDenmark
    

    然后:

    $xml = file_get_contents('http://www.google.com/ig/api?weather='.$city);
    $xml = mb_convert_encoding($xml, 'UTF-8');
    $xml = simplexml_load_string($xml);
    echo $xml->weather->forecast_information->city['data'];
    

    预期输出:

    Søborg, Capital Region of Denmark
    

    【讨论】:

    • 太棒了!你能告诉我正确的方法是什么,把“ø”变成%C3%B8?有内置功能吗?
    • 确实如此,但我从 geoplugin.net xml 获得的字符串似乎(根据 mb_detect_encoding())是 ASCII 格式,所以当我 rawurlencode() 它时,我得到 @987654330 @回来。我搜索了a way to convert ASCII to UTF-8 并了解到ASCII 实际上是UTF-8 的一个子集。我已经按照链接中的建议尝试了$string = iconv('ASCII', 'UTF-8//IGNORE', $geo_city); echo mb_detect_encoding($string);,它仍然返回 ASCII。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-11
    • 2014-10-28
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多