Search code examples
phpjsoncurlfile-get-contents

How can I get JSON data from a URL using PHP? I'm getting authentication failure


This is a public URL for JSON weather data from the US National Weather Service.

https://forecast.weather.gov/MapClick.php?lat=39.71&lon=-104.76&FcstType=json

If I enter this URL is a browser's address bar (or click the link above), I get exactly the JSON data I want. But all my attempts with PHP (in my WordPress website) result in authentication errors. I've tried variations of StackOverflow suggestions along this line:

$json = file_get_contents('url_here');
$obj = json_decode($json);
echo $obj->access_token;

I've tried several variations of StackOverflow suggestions along this line:

$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_URL, 'url_here');
$result = curl_exec($ch);
curl_close($ch);

$obj = json_decode($result);
echo $obj->access_token;

In all cases, I get authentication errors:

Access Denied
You don't have permission to access "http://forecast.weather.gov/MapClick.php?" on this server.

Reference #18.d56775c7.1554244115.21225898

The fact that the error message stops at the "?" in the URL makes me wonder if I need to pass PHP parameters by a method other than simply appending them to the URL.

I assume I don't need authentication information (username, password) because the NWS data is intended to be public.

Suggestions would be appreciated.


Solution

  • It looks like the site you're trying to access is expecting a user agent.

    No worries, we can easily do this with cURL:

    <?php
        function curler ($url)
        {
            $ch = curl_init();
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_USERAGENT , "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1)");
            $output = curl_exec($ch);
            curl_close($ch);
            return json_decode($output);
        }
    
        var_dump (
            curler("https://forecast.weather.gov/MapClick.php?lat=39.71&lon=-104.76&FcstType=json")
        );
    

    Which will return the data you expect in an object.