Обновление данных геолокации, полученных из API через запрос cURL, через определенный интервал времени - PullRequest
0 голосов
/ 27 октября 2019

Я получаю два значения (широта, долгота) через API с запросом cURL. Мой запрос выглядит следующим образом:

function APIcall($method, $url, $data){
   $curl = curl_init();

   switch ($method){
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);                              
         break;
      default:
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   }

   // OPTIONS:
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      'APIKEY: example-key-here',
      'Content-Type: application/json',
   ));
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

   // EXECUTE:
   $result = curl_exec($curl);
   if(!$result){die("Connection Failure");}
   curl_close($curl);
   return $result;
}

$get_data = APIcall('GET', 
'https://api.wheretheiss.at/v1/satellites/25544', false);
$response = json_decode($get_data, true);

Этот вызов находится в отдельном файле apicall.php в моей корневой папке, который я затем могу эффективно указать там, где он мне нужен. Когда я это делаю, я использую значения, данные мне в переменной $response, чтобы отобразить значение широты и долготы, что мне и нужно:

echo $response['latitude'];
echo $response['longitude'];

Я делаю это внутритег script моей карты Leaflet.js для размещения на нем маркера в координатах, которые предоставляет API:

mymap.setView([<?php echo $response['latitude']; ?>, <?php echo $response['longitude']; ?>], mymap.getZoom());  
marker.setLatLng([<?php echo $response['latitude']; ?>, <?php echo $response['longitude']; ?>]);

. Здесь возникает моя проблема. Мой код выше, размещает маркер только один раз, так как вызов производится только один раз (конечно). Как мне делать больше звонков через определенный промежуток времени без перезагрузки всей моей страницы?

1 Ответ

0 голосов
/ 27 октября 2019

Если вы просматриваете заголовки ответов при просмотре конечной точки API, вы должны заметить, что у них есть Access-Control-Allow-Origin: *, что означает, что вы можете сделать HttpRequest непосредственно из Javascript. Вы можете сделать это с помощью Ajax или Fetch - в следующем я выбрал Fetch, поскольку это такая простая задача с этим API. Без сомнения, есть аналогичные опции, доступные непосредственно из jQuery, но, поскольку я не использую его, я не могу советовать, и когда вы посмотрите на код, вы не увидите реальной необходимости использовать его в этом случае. Поскольку API был открыт для всех источников, запрос скручивания действительно не требуется!

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Where is the ISS?</title>
        <script>
            document.addEventListener('DOMContentLoaded',()=>{
                /* api endpoint */
                let url='https://api.wheretheiss.at/v1/satellites/25544';

                /* only for demo purposes - display output in this element */
                let out=document.querySelector('output');

                /* ultra simple callback to display data from API */
                const callback=function( r ){
                    out.innerText=Object.keys(r).map( ( k )=>{
                        return [ k, r[ k ] ].join( ':' )
                    }).join( String.fromCharCode( 10 ) )
                };

                /* Send a basic request to the api ( which returns JSON ) and process using callback */
                const fetchposition=function( url, callback ){
                    fetch( url ).then( r=>{ return r.json() } ).then( callback )
                };

                /* 
                    create a self-executing anonymous function with relevant 
                    parameters ~ this is in the John Resig style... 

                    This acts like `setInterval` or a self referencing `setTimeout`

                */
                (function( url, delay, callback ){
                    (function(){
                        setTimeout( arguments.callee, 1000 * delay );
                        fetchposition( url, callback );
                    })();
                })( url, 5, callback );             
            });
        </script>
    </head>
    <body>
        <output></output>
    </body>
</html>

Пример данных за одну итерацию:

name:iss
id:25544
latitude:34.995889522375
longitude:129.28250031522
altitude:422.37051205509
velocity:27577.33696572
visibility:eclipsed
footprint:4519.5039529858
timestamp:1572204467
daynum:2458784.3109606
solar_lat:-12.881716643173
solar_lon:244.02703108844
units:kilometers

Из этого следует легко изменитьположение маркера на карте - или добавьте новый маркер для каждого результата ...


После комментария относительно actual api ~ в верхней части кода PHP отправьте запрос API с помощью curl.

<?php
    if($_SERVER['REQUEST_METHOD']=='POST' && !empty( $_POST['query'] ) ){
        ob_clean();
        # send api request ~ using cURL, carrier pigeon or whatever
        exit( date( DATE_ATOM ) );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Where is the ISS?</title>
        <script>
            document.addEventListener('DOMContentLoaded',()=>{

                let out=document.querySelector('output');

                const ajaxcallback=function(r){
                    let div=document.createElement('div');
                        div.innerText=r;
                    out.appendChild( div ); 
                };
                const ajax=function(url,params,callback){
                    let xhr=new XMLHttpRequest();
                        xhr.onload=function(){
                            if( this.status==200 && this.readyState==4 )callback( this.response )
                        };
                        xhr.open( 'POST', url, true );
                        xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
                        xhr.send( params );
                };


                (function( url, delay, callback ){
                    (function(){
                        setTimeout( arguments.callee, 1000 * delay );
                        ajax( url, 'query=api', callback )
                    })();
                })( 'apicall.php', 5, ajaxcallback );               
            });

        </script>
    </head>
    <body>
        <output></output>
    </body>
</html>
...