【问题标题】:file_get_contents() returns FALSE while simple GET request via Chrome returns JSON datafile_get_contents() 返回 FALSE,而通过 Chrome 的简单 GET 请求返回 JSON 数据
【发布时间】:2020-02-06 01:41:22
【问题描述】:

我不确定为什么会出现这种行为?我正在尝试在我的 PHP 脚本中实现 Blockchain.com Web API。他们的documentation states 我应该使用file_get_contents PHP 函数来查询它,我这样做:

$xpub = "xpub123455";
$callback_url = "https://example.com";
$APIKey = "12345";
$url = "https://api.blockchain.info/v2/receive?xpub=".urlencode($xpub).'&callback='.urlencode($callback_url).'&key='.urlencode($APIKey);
//echo("URL: ".htmlentities($url)."<br><br>");
$res = @file_get_contents($url);
if($res)
{
    echo("RES: ".htmlentities(var_export($res, true)));
}
else
{
    $err = error_get_last();
    echo("err: ".($err && isset($err['message']) ? $err['message'] : "-"));
}

在这种情况下,file_get_contents 返回false,如果我再调用error_get_last,我会收到以下错误:

错误:file_get_contents(-url-):打开流失败:HTTP 请求失败! HTTP/1.1 401 未经授权

但如果我只是复制传递给 Chrome 的 file_get_contentspaste it into the address bar 的 URL:

https://api.blockchain.info/v2/receive?xpub=xpub123455&callback=https%3A%2F%2Fexample.com&key=12345

它返回一个有效的 JSON 数据:

为什么这两个输出不同?以及如何从file_get_contents 获得 JSON 响应?

【问题讨论】:

  • 该端点可能会检查请求的用户代理,是否有任何类似于实际当前浏览器的内容 - 如果不存在,它会拒绝请求(或者可能需要额外的身份验证。)
  • 这能回答你的问题吗? How do I get PHP errors to display?
  • 使用 Chrome 检查器查看 HTTP 请求的内容(标头等),并使用 curl 发出类似的请求(有很多 curl 选项)。 php.net/manual/en/book.curl.php

标签: php blockchain.info-api


【解决方案1】:

allow_url_fopen 功能可能受到限制。

最好使用 cURL 而不是 file_get_contents:

function url_get_contents ($Url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $Url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}

那么你就可以使用这个功能了:

$res = @url_get_contents($url);

【讨论】:

  • 不错。谢谢。那里应该有某种try/catch 部分吗?
  • “allow_url_fopen 函数可能受到限制” - 这当然绝对不是这里的问题。如果是这样的话,它甚至不会得到一个实际的 HTTP 响应代码。另外,如果是这种情况,错误消息会很清楚地说明。
  • 请在您的答案中添加更多解释,以便其他人可以从中学习。比如为什么要抑制 cURL 抛出的错误?
【解决方案2】:

回答这个问题:

我如何从 file_get_contents 获得 JSON 响应?

您可以从file_get_contents 获取json 响应(我在这里添加了http.ignore_errors 标志,这将防止PHP 抛出错误):

$xpub = "xpub123455";
$callback_url = "https://example.com";
$APIKey = "12345";
$url = "https://api.blockchain.info/v2/receive?xpub=".urlencode($xpub).'&callback='.urlencode($callback_url).'&key='.urlencode($APIKey);

//add http.ignore_errors flag here 
$res = file_get_contents($url, false, stream_context_create([
    "http" => [
      'ignore_errors' => true
    ]
]));

/*
 * string(40) "{message" : "API Key is not valid"}"
 */
var_dump($res);

您能否分享 api 密钥,因为在获得 api 密钥之前您必须通过审核过程,因此帮助有点困难。因此无法重现错误。

【讨论】:

  • 请在您的答案中添加一些解释,以便其他人可以从中学习。你改变了什么,为什么?
猜你喜欢
  • 1970-01-01
  • 2021-01-01
  • 1970-01-01
  • 2019-01-09
  • 2013-01-25
  • 1970-01-01
  • 2014-04-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多