【问题标题】:XML-JSON content negotiationXML-JSON 内容协商
【发布时间】:2013-02-07 20:14:04
【问题描述】:

我希望只显示以下页面中的某些内容:http://sc2ranks.com/api/psearch/am/MxGPezz/1t/division/Felanis%20Sierra?appKey=sentinelgaming.net。到目前为止,我可以使用下面的 php 显示一些东西,但它甚至不是正确的数字。有人能告诉我如何从这个 XML 网页显示这个播放器的“成就点”吗?

$url = 'http://sc2ranks.com/api/psearch/am/MxGPezz/1t/division/Felanis%20Sierra?appKey=sentinelgaming.net';
$xml = file_get_contents($url);

echo $xml->achievement-points;

谢谢

【问题讨论】:

  • $xml = [{"achievement_points":580,"character_code":0,"team":{"points":1308,"wins":127,"losses":104,"division_id":351726,"division_name":"Division Felanis Sierra","id":12366704},"region":"us","bnet_id":2868603,"name":"MxGPezz","id":3416151}]' (length=233) 奇怪!
  • 不奇怪——服务器正在使用内容协商。

标签: php xml json


【解决方案1】:

此文件的内容类型取决于Accept 标头或format 查询参数。看来您至少可以检索 XML 或 JSON。

您从file_get_contents() 获得的默认值将是 JSON,因为它不包含 Accept 请求标头,但来自浏览器的默认值将是 XML,因为浏览器通常在其 Accept 请求标头中包含 XML mime 类型.

获取 JSON:

$url = 'http://sc2ranks.com/api/psearch/am/MxGPezz/1t/division/Felanis%20Sierra?appKey=sentinelgaming.net';

// &format=json is not strictly necessary,
// but it will give you fewer surprises
$json = file_get_contents($url.'&format=json');
$records = json_decode($json);
echo $records[0]->achievement_points, "\n";

获取 XML:

$sxe = simplexml_load_file($url.'&format=xml');
echo (string) $sxe->record->{'achievement-points'}, "\n";

要使用$sxe 对象,请参阅this SimpleXML cheat sheet

您可以设置Accept 标头,而不是使用format 参数。您还可以添加一些抽象来获取 url,以便您也可以检索内容类型和编码。请参见下面的示例。

function get_url($url, $context=null) {
    $response = file_get_contents($url, false, $context);
    $ctypeheaders = preg_grep('/^Content-Type:\s/i', $http_response_header);
    $ctype = NULL;
    if ($ctypeheaders) {
        $ctype = end($ctypeheaders);
        $ctype = end(explode(':', $ctype, 2));
        $ctype = explode(';', $ctype, 2);
        $charset = isset($ctype[1]) ? $ctype[1] : '';
        if ($charset && preg_match('/charset\s*=\s*([^\s]+)/i', $charset, $matches)) {
            $charset = $matches[1];
        }
        $ctype[1] = $charset;
        $ctype = array_map('trim', $ctype);
    }
    return array($response, $ctype);
}

然后您可以像这样使用get_url()

// With no accept header, just see what we get:
list($content, $contenttype) = get_url($url);
list($type, $encoding) = $contenttype;
// $type will be 'application/xml' or 'application/json'
// $encoding is very handy to know too

// Or we can specify an accept header:
$opt_accept_xml = stream_context_create(array(
    'http' => array(
        'header' => "Accept: application/xml\r\n"
    )
));

list($content, $contenttype) = get_url($url, $opt_accept_xml);

【讨论】:

  • 我无法显示任何内容,即使我认为这是朝着正确方向迈出的一步。无论我用这种方法使用什么变体,都会变成空白。
  • file_get_contents() 是一个字符串——你必须解析它。此外,此 url 将 json 返回到 PHP,而不是 XML。查看更新的答案。
  • 天哪,非常感谢弗朗西斯,我真的很感激!我第一次看到它通过多次发布这个问题而起作用。只有有意义的答案!
  • 添加'&format=xml' 是否可以解决类似情况下的问题?我看到这是一个nginx/0.8.53 + Phusion Passenger 3.0.1 (mod_rails/mod_rack) 服务器
  • 我们能否在需要时制作 file_get_contents()simplexml_load_file() 记录 HTTP 标头?
【解决方案2】:

也许:

    echo $xml->record[0]->achievement-points;

【讨论】:

  • 由于某种原因,即使“0”不是该用户的正确成就点数,也会出现“0”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-08
  • 2014-12-22
  • 2015-08-06
  • 2011-02-05
  • 2012-08-13
  • 1970-01-01
相关资源
最近更新 更多