0

I'm not sure why am I getting this behavior? I'm trying to implement the Blockchain.com web APIs in my PHP script. Their documentation states that I should use file_get_contents PHP function to query it, which I do as such:

$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'] : "-"));
}

In that case file_get_contents returns false and if I then call error_get_last, I get the following error:

err: file_get_contents(-url-): failed to open stream: HTTP request failed! HTTP/1.1 401 Unauthorized

But if I just copy the URL that is being passed to file_get_contents and paste it into the address bar for Chrome:

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

it returns a valid JSON data:

enter image description here

Why are these two outputs different? And how can I get a JSON response from file_get_contents?

c00000fd
  • 20,994
  • 29
  • 177
  • 400
  • That endpoint probably checks the User-Agent of the request, for anything that resembles an actual, current browser - and if that’s not present, it rejects the request (or requires additional authentication, maybe.) – 04FS Feb 06 '20 at 08:27
  • Does this answer your question? [How do I get PHP errors to display?](https://stackoverflow.com/questions/1053424/how-do-i-get-php-errors-to-display) – Nico Haase Nov 17 '21 at 10:35
  • Use the Chrome inspector to see what the HTTP request has (header, etc.), and make a similar request using curl (there are a lot of curl options for that). https://www.php.net/manual/en/book.curl.php – José Carlos PHP Nov 17 '21 at 11:54

2 Answers2

1

The allow_url_fopen function is probably restricted.

It is better to use cURL instead of 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;
}

then you can use this function:

$res = @url_get_contents($url);
Mahdi Shad
  • 1,427
  • 1
  • 14
  • 23
  • Nice. Thanks. Should there be some sort of a `try`/`catch` section there? – c00000fd Feb 06 '20 at 03:16
  • _“The allow_url_fopen function is probably restricted”_ - that’s of course absolutely not the issue here. If that was the case, it would not even get as far as getting an actual HTTP response code. Plus, the error message would pretty clearly say if this was the case. – 04FS Feb 06 '20 at 08:25
  • Please add some more explanation to your answer such that others can learn from it. For example, why do you suppress the errors thrown by cURL? – Nico Haase Nov 17 '21 at 12:38
0

To answer this question:

And how can I get a JSON response from file_get_contents?

You can obtain a json response from file_get_contents with (I added a http.ignore_errors flag here, this will prevent PHP from throwing an error):

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

Could you share the api key since helping is a bit difficult since you must go through a review process before you get an api key. And therefor it is not possible to reproduce the error.

Douma
  • 2,682
  • 14
  • 23
  • Please add some explanation to your answer such that others can learn from it. What did you change, and why? – Nico Haase Nov 17 '21 at 10:36