API OWM impossible de recuperer les donnees

Par Julien-Lanza, il y a 5 ans


Bonjour,

Voila je rencontre un petit problème avec mon code.

Je suis bloque au niveau de la recuperation des donnes depuis OWM.

public function getForecast(string $city): ?array { $data = $this->callAPI("forecast/daily?q={$city}"); foreach($data['list'] as $day) { $results[] = [ 'temp' => $day['temp']['day'], 'description' => $day['weather'][0]['description'], 'date' => new DateTime('@' . $day['dt']) ]; } return $results; }

Je recupere :

! ) Warning: Invalid argument supplied for foreach() in /Users/julienpassard/Documents/TutorielPHP/class/OpenWeather.php on line 24 Call Stack # Time Memory Function Location 1 0.0014 403112 {main}( ) .../meteo.php:0 2 0.0017 411648 OpenWeather->getForecast( ) .../meteo.php:7 ( ! ) Notice: Undefined variable: results in /Users/julienpassard/Documents/TutorielPHP/class/OpenWeather.php on line 31 Call Stack # Time Memory Function Location 1 0.0014 403112 {main}( ) .../meteo.php:0 2 0.0017 411648 OpenWeather->getForecast( ) .../meteo.php:7 ( ! ) Notice: Undefined variable: results in /Users/julienpassard/Documents/TutorielPHP/class/OpenWeather.php on line 31 Call Stack # Time Memory Function Location 1 0.0014 403112 {main}( ) .../meteo.php:0 2 0.0017 411648 OpenWeather->getForecast( ) .../meteo.php:7 En ce moment °C ( ! ) Warning: Invalid argument supplied for foreach() in /Users/julienpassard/Documents/TutorielPHP/meteo.php on line 21 Call Stack # Time Memory Function Location 1 0.0014 403112 {main}( ) .../meteo.php:0

Si je prends le fichier de la lecon suivante, je recupere

name lookup timed out

Merci pour votre aide.

5 réponses

Kareylo, il y a 5 ans

Tu as plusieurs problèmes dans ton code et qui te sont retourné dans ton message d'erreur :

( ! ) Notice: Undefined variable: results in /Users/julienpassard/Documents/TutorielPHP/class/OpenWeather.php on line 31 Call Stack # Time Memory Function Location 1 0.0014 403112 {main}( ) .../meteo.php:0 2 0.0017 411648 OpenWeather->getForecast( ) .../meteo.php:7

Celui-ci te dit que la variable results n'existe pas.
Créé une variable results en tant que tableau avant ta boucle.

Ensuite, pour le problème avec le foreach, je me demande si tu n'aurais pas des données vides, pense à vérifier que ces données existent avant de les parcourir.

Julien-Lanza, il y a 5 ans

Hi Kareylo,
merci pour ta reponse!

En effet en faisant des tests, je me suis apercu que $results est en effet vide.

voici le code complet de la classe OpenWeather, j'ai aussi vu dans les messages SEB86 parle d'un changement a effectuer. Jai essaye mais le resultat est toujours le meme... [(https://www.grafikart.fr/tutoriels/curl-php-1138)]

<?php class OpenWeather { private $apiKey; public function __construct(string $apiKey) { $this->apiKey = $apiKey; } public function getToday(string $city): ?array { $data = $this->callAPI("weather?q={$city}"); return [ 'temp' => $data['main']['temp'], 'description' => $data['weather'][0]['description'], 'date' => new DateTime() ]; } public function getForecast(string $city): ?array { $data = $this->callAPI("forecast/daily?q={$city}"); foreach($data['list'] as $day) { $results[] = [ 'temp' => $day['temp']['day'], 'description' => $day['weather'][0]['description'], 'date' => new DateTime('@' . $day['dt']) ]; } return $results; } private function callAPI(string $endpoint): ?array { $curl = curl_init("http://api.openweathermap.org/data/2.5/{$endpoint}&units=metric&lang=fr&APPID={$this->apiKey}&units=metric&lang=fr"); curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CAINFO => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cert.cer', CURLOPT_TIMEOUT => 1 ]); $data = curl_exec($curl); if ($data === false || curl_getinfo($curl, CURLINFO_HTTP_CODE) !== 200) { return null; } return json_decode($data, true); } }

Le fichier meteo.php contenant mon APIKey

<?php require_once 'class/OpenWeather.php'; $weather = new OpenWeather('7f5e587cc9d81bc6f413c3929161f1ea'); $forecast = $weather->getForecast('Montpellier,fr'); $today = $weather->getToday('Montpellier,fr'); require 'elements/header.php'; ?> <div class="container"> <ul> <li>En ce moment <?= $today['description'] ?> <?= $today['temp'] ?>°C</li> <?php foreach($forecast as $day): ?> <li><?= $day['date']->format('d/m/Y') ?> <?= $day['description'] ?> <?= $day['temp'] ?>°C</li> <?php endforeach ?> </ul> </div> <?php require 'elements/footer.php';

Aussi, si je passe cette adresse
[(https://samples.openweathermap.org/data/2.5/weather?q=London&appid=7f5e587cc9d81bc6f413c3929161f1ea)]

ca me renvoie bien un tableau JSON

coord lon -0.13 lat 51.51 weather 0 id 300 main "Drizzle" description "light intensity drizzle" icon "09d" base "stations" main temp 280.32 pressure 1012 humidity 81 temp_min 279.15 temp_max 281.15 visibility 10000 wind speed 4.1 deg 80 clouds all 90 dt 1485789600 sys type 1 id 5091 message 0.0103 country "GB" sunrise 1485762037 sunset 1485794875 id 2643743 name "London" cod 200

J'espere que mon explication est comprehensible ;)

Merci d'avance

Julien-Lanza, il y a 5 ans

et en faisant un "var_dump($data)"

private function callAPI(string $endpoint): ?array { $curl = curl_init("http://api.openweathermap.org/data/2.5/{$endpoint}&units=metric&lang=fr&APPID={$this->apiKey}&units=metric&lang=fr"); curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CAINFO => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cert.cer', CURLOPT_TIMEOUT => 1 ]); $data = curl_exec($curl); var_dump($data); die; if ($data === false || curl_getinfo($curl, CURLINFO_HTTP_CODE) !== 200) { return null; } return json_decode($data, true); }

je recupere

/Users/julien/Documents/TutorielPHP/class/OpenWeather.php:43:boolean false

Julien-Lanza, il y a 5 ans

Hi Nikkinemo95,

I now got a step further. I am getting the TEMP data, I mean now I can see the temperature of the current day when I insert my APIkey

if you use this APIKey (from the tutorial) :94c6cf0868fa5cb930a5e2d71baf0dbf
you get all data working.
So I guess it is about the subscription we have related to our APIKey.
I jumped to the next lessons but I still would like to know if my guess is right ;)

meteo.php:

<?php require_once 'vendor/autoload.php'; $weather = new App\OpenWeather('7f5e587cc9d81bc6f413c3929161f1ea'); $error = null; try { $forecast = $weather->getForecast('Montpellier,fr'); $today = $weather->getToday('Montpellier,fr'); } catch (Exception | Error $e) { $error = $e->getMessage(); } require 'elements/header.php'; ?> <?php if ($error): ?> <div class="alert alert-danger"><?= $error ?></div> <?php else: ?> <div class="container"> <ul> <li>En ce moment <?= $today['description'] ?> <?= $today['temp'] ?>°C</li> <?php foreach($forecast as $day): ?> <li><?= $day['date']->format('d/m/Y') ?> <?= $day['description'] ?> <?= $day['temp'] ?>°C</li> <?php endforeach ?> </ul> </div> <?php endif ?> <?php require 'elements/footer.php';

OpenWeather class :

<?php namespace App; class OpenWeather { private $apiKey; public function __construct(string $apiKey) { $this->apiKey = $apiKey; } public function getToday(string $city): ?array { $data = $this->callAPI("weather?q={$city}"); return [ 'temp' => $data['main']['temp'], 'description' => $data['weather'][0]['description'], 'date' => new \DateTime() ]; } public function getForecast(string $city): ?array { $data = $this->callAPI("forecast/daily?q={$city}"); foreach($data['list'] as $day) { $results[] = [ 'temp' => $day['temp']['day'], 'description' => $day['weather'][0]['description'], 'date' => new \DateTime('@' . $day['dt']) ]; } return $results; } private function callAPI(string $endpoint): ?array { $curl = curl_init("http://api.openweathermap.org/data/2.5/{$endpoint}&units=metric&lang=fr&APPID={$this->apiKey}&units=metric&lang=fr"); curl_setopt_array($curl, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_CAINFO => dirname(__DIR__) . DIRECTORY_SEPARATOR . 'cert.cer', CURLOPT_TIMEOUT => 1 ]); $data = curl_exec($curl); if ($data === false || curl_getinfo($curl, CURLINFO_HTTP_CODE) !== 200) { return null; } return json_decode($data, true); } }
Lartak, il y a 5 ans

Bonsoir.
Tu n'as toujours fais aucune des correction que t'a indiqué Kareilo, avant ta boucle il te faut d'abord vérifier que ta variable data retourne bien un tableau de données et non null avant de faire la boucle et il te faut également initialiser la variable results avec un tableau vide, demanière à éviter la seconde erreur qui t'était retournée.
Soit par exemple :

$data = $this->callAPI("forecast/daily?q={$city}"); $results = []; if ($data !== null) { // ensuite ta boucle } return $results;