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


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.

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

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

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

}

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;