Search code examples
phpjsoncodeigniterfile-get-contents

Get data from accuweather api url


I am trying to get json data from the accuweather API for a locationKey in PHP. The output is as: file_get_contents(https://dataservice.accuweather.com/forecasts/v1/daily/1day/55488?apikey=0NSY9T1tFGo0NIXOYp23lro8DsuOcwPJ): failed to open stream: HTTP request failed!

<?php
$url = "https://dataservice.accuweather.com/forecasts/v1/daily/1day/55488?apikey=0NSY9T1tFGo0NIXOYp23lro8DsuOcwPJ";
$json = file_get_contents($url);
$data = json_decode($json,true);
print_r($data);
?>

allow_url_fopen is enabled.

what do i do?

Edit: I changed the code as follows and it did not work

function weather(){
    $url='http://dataservice.accuweather.com/forecasts/v1/daily/5day/55488?apikey=0NSY9T1tFGo0NIXOYp23lro8DsuOcwPJ';
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl,CURLOPT_FAILONERROR,true);
    curl_setopt($curl, CURLOPT_URL, $url);
    $result = curl_exec($curl);
    $res=(object)array(
        'response'  =>  curl_exec( $curl ),
        'status'    =>  curl_getinfo( $curl, CURLINFO_RESPONSE_CODE ),
        'info'      =>  (object)curl_getinfo( $curl ),
        'errors'    =>  curl_error( $curl )
    );
    curl_close($curl);

    echo 'response:'.$res->response;
    echo '<br>';
    echo 'status:'.$res->status;
    echo '<br>';
    echo 'errors:'.$res->errors;

}

Result is blank page with the following characteristics:

response:  
status:0  
errors:Empty reply from server

Solution

  • The Fetch api seems like the easiest solution as the endpoint does have the Access-Control-Allow-Origin: * header present - a simple example below to illustrate the basics.

    const url='https://dataservice.accuweather.com/forecasts/v1/daily/1day/55488?apikey=0NSY9T1tFGo0NIXOYp23lro8DsuOcwPJ';
    
    
    fetch( url )
      .then( r=>r.json() )
      .then( json=>{
        const out=document.querySelector('output');
        
        Object.keys( json ).forEach( k=>{
          let div=document.createElement('div');
              out.append( div );
          let h1=document.createElement('h1');
              h1.textContent=k;
              div.append(h1);
              
          // etc
        });
        
        json.DailyForecasts.forEach( obj=>{
          console.info( obj )
        })
        
      })
    <output></output>

    In PHP you can use curl to easily fetch the response from the AccuWeather API. The following curl function has a cacert variable which points t oa valid cacert.pem file - this is usually needed when negotiating SSL connections as here.

    <?php
                
        function curl( $url=false ){
            $cacert='c:/wwwroot/cacert.pem';
            
            $curl=curl_init();
            if( parse_url( $url, PHP_URL_SCHEME )=='https' ){
                curl_setopt( $curl, CURLOPT_SSL_VERIFYPEER, true );
                curl_setopt( $curl, CURLOPT_SSL_VERIFYHOST, 2 );
                curl_setopt( $curl, CURLOPT_CAINFO, $cacert );
            }
    
            curl_setopt( $curl, CURLOPT_URL, trim( $url ) );
            curl_setopt( $curl, CURLOPT_FOLLOWLOCATION, true );
            curl_setopt( $curl, CURLOPT_FAILONERROR, true );
            curl_setopt( $curl, CURLOPT_RETURNTRANSFER, true );
            curl_setopt( $curl, CURLOPT_TIMEOUT, 60 );
            curl_setopt( $curl, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; Win64; x64)' );
            curl_setopt( $curl, CURLOPT_ENCODING, '' );
    
            $res=(object)array(
                'response'  =>  curl_exec( $curl ),
                'status'    =>  curl_getinfo( $curl, CURLINFO_RESPONSE_CODE ),
                'info'      =>  (object)curl_getinfo( $curl ),
                'errors'    =>  curl_error( $curl )
            );
            curl_close( $curl );
            return $res;
        }
        
        
        $url='https://dataservice.accuweather.com/forecasts/v1/daily/1day/55488?apikey=0NSY9T1tFGo0NIXOYp23lro8DsuOcwPJ';
        $res=curl( $url );
        if( $res->status==200 ){
            printf('<pre>%s</pre>',print_r( json_decode( $res->response ),true ) );
        }
        
    ?>
    

    And this yields:

    stdClass Object
    (
        [Headline] => stdClass Object
            (
                [EffectiveDate] => 2022-01-14T07:00:00-05:00
                [EffectiveEpochDate] => 1642161600
                [Severity] => 4
                [Text] => Turning much colder today and tomorrow
                [Category] => cooler
                [EndDate] => 2022-01-15T19:00:00-05:00
                [EndEpochDate] => 1642291200
                [MobileLink] => http://www.accuweather.com/en/ca/toronto/m5h/daily-weather-forecast/55488?lang=en-us
                [Link] => http://www.accuweather.com/en/ca/toronto/m5h/daily-weather-forecast/55488?lang=en-us
            )
    
        [DailyForecasts] => Array
            (
                [0] => stdClass Object
                    (
                        [Date] => 2022-01-13T07:00:00-05:00
                        [EpochDate] => 1642075200
                        [Temperature] => stdClass Object
                            (
                                [Minimum] => stdClass Object
                                    (
                                        [Value] => 12
                                        [Unit] => F
                                        [UnitType] => 18
                                    )
    
                                [Maximum] => stdClass Object
                                    (
                                        [Value] => 34
                                        [Unit] => F
                                        [UnitType] => 18
                                    )
    
                            )
    
                        [Day] => stdClass Object
                            (
                                [Icon] => 19
                                [IconPhrase] => Flurries
                                [HasPrecipitation] => 
                            )
    
                        [Night] => stdClass Object
                            (
                                [Icon] => 43
                                [IconPhrase] => Mostly cloudy w/ flurries
                                [HasPrecipitation] => 
                            )
    
                        [Sources] => Array
                            (
                                [0] => AccuWeather
                            )
    
                        [MobileLink] => http://www.accuweather.com/en/ca/toronto/m5h/daily-weather-forecast/55488?lang=en-us
                        [Link] => http://www.accuweather.com/en/ca/toronto/m5h/daily-weather-forecast/55488?lang=en-us
                    )
    
            )
    
    )