PHP, XML & Prévisions Météo

On ne sait plus trop comment s'habiller ces jours-ci. Un jour on se ballade poils au vent, caressé par un soleil complice et le lendemain on rentre du travail en vélo, arrosé par une pluie moqueuse. Un climat indécis, idéal pour présenter ma dernière classe : WdWeather.

Présentation

Utilisant les services pratiques et connus de weather.com, WdWeather permet d'obtenir les prévisions météorologiques jusqu'à 10 jours (limite imposée par le service). Les informations sont aussi nombreuses que variées. Ainsi pour chaque jour on obtient, en autre, les informations suivantes :

  • Les heures de lever et de coucher du soleil
  • Les températures les plus basse et les plus hautes

Et pour chaque période de la journée (Jour / Nuit) :

  • Le numéro du pictogramme associé au temps.
  • Une description du temps en anglais, par exemple : Mostly Sunny.
  • La force et la direction du vent.
  • Les précipitations.
  • Le taux d'humidité.

Bref, il y a de quoi faire.
Voyons justement comment tout ça marche.

Comment ça marche ?

C'est vraiment très simple. Le principe est le suivant:

  1. On demande le code de la ville dont on souhaite connaitre les prévisions météo.
  2. On demande les prévisions météo pour les jours à venir.
  3. On affiche le résultat.

C'est tellement fastoche que je me suis presque endormi en écrivant les étapes.

Le Code

<?php

class WdWeather
{
    var $markup_contents = '([^<]+)';
    
    function getCityCode($search)
    {
        #
        # we create a nice looking URL
        #
        
        $search = explode(','$search);
        $search = array_map('urlencode'$search);
        $search = implode(',+'$search);
        
        #
        # ask the service about the location
        #
    
        $xml = file_get_contents
        (
            'http://xml.weather.com/search/search?where=' . $search
        );
        
        #
        # try to get the first result
        #
        
        if (!preg_match('#loc id="([^"]+)#'$xml$matches))
        {
            return;
        }
        
        return $matches[1];
    }

    function getWeather($city_code$days)
    {
        $xml = file_get_contents
        (
            'http://xml.weather.com/weather/local/' . $city_code .
            '?cc=*&unit=s&dayf=' . $days
        );
        
        if (!$xml)
        {
            return;
        }
        
        return $this->parseDays($xml);
    }
    
    function parseDays($xml)
    {
        $days = array();
        
        #
        # split xml by days
        #

        $parts = preg_split('#<day d=[^>]+>#'$xml);

        array_shift($parts);

        $mc = $this->markup_contents;

        foreach ($parts as $xml)
        {
            $days[] = $this->parseDay($xml);
        }
        
        return $days;
    }

    function parseDay($xml)
    {
        $mc = $this->markup_contents;
    
        preg_match
        (
            '#' .
            
            '<hi>' . $mc . '</hi>\s*' .
            '<low>' . $mc . '</low>\s*' .
            '<sunr>' . $mc . '</sunr>\s*' .
            '<suns>' . $mc . '</suns>\s*' .
            '<part p="d">(.*)</part>\s*' .
            '<part p="n">(.*)</part>' .
            
            '#ms',
            
            $xml$matches
        );
        
        array_shift($matches);
                    
        #
        # parse day periods (day / night)
        #
        
        $matches[4] = $this->parseDayPeriod($matches[4]);
        $matches[5] = $this->parseDayPeriod($matches[5]);
        
        #
        #
        #
        
        return array_combine
        (
            array('hi''low''sunr''suns''day''night')$matches
        );
    }
    
    function parseDayPeriod($xml)
    {
        $mc = $this->markup_contents;

        preg_match
        (
            '#' .
            
            '<icon>' . $mc . '</icon>\s*' .
            '<t>' . $mc . '</t>\s*' .
            '<wind>(.*)</wind>\s*' .
            '<bt>' . $mc . '</bt>\s*' .
            '<ppcp>' . $mc . '</ppcp>\s*' .
            '<hmid>' . $mc . '</hmid>' .
            
            '#ms',
            
            $xml$matches
        );
        
        array_shift($matches);
        
        $matches[2] = $this->parseWind($matches[2]);
        
        return array_combine
        (
            array('icon''t''wind''bt''ppcp''hmid')$matches
        );
    }
    
    function parseWind($xml)
    {
        $mc = $this->markup_contents;

        preg_match
        (
            '#' .
            
            '<s>' . $mc . '</s>\s*' .
            '<gust>' . $mc . '</gust>\s*' .
            '<d>' . $mc . '</d>\s*' .
            '<t>' . $mc . '</t\s*' .
            
            '#ms',
            
            $xml$matches
        );
        
        array_shift($matches);
        
        return array_combine
        (
            array('s''gust''d''t')$matches
        );
    }

    static function toCelsius($f)
    {
        if (!is_numeric($f))
        {
            return $f;
        }
    
        return round(($f-32) * 5 / 9);
    }
    
    static function to24H($time)
    {
        preg_match('#(\d+)\:(\d+)\s+(AM|PM)?#'$time$matches);
        
        if ($matches[3] == 'PM')
        {
            $matches[1] += 12;
        }

        return $matches[1] . ':' . $matches[2];
    }
}

L'exemple

Trois lignes d'initialisation :

  1. On crée l'objet.
  2. On récupère le code de la ville qui nous intéresse. Ici Toulouse, parce que c'est chez moi.
  3. On récupère les prévisions météo pour les quatre jours qui viennent.
<?php

$weather = new WdWeather();

$code = $weather->getCityCode('Toulouse, France');
$days = $weather->getWeather($code4);

define('WEATHER_ICONS_URL''wdweather/');

On met tout ça dans un tableau

<table id="weather" cellpadding="4" cellspacing="0">
<tr>

Pour chaque jour on affiche les informations suivantes :

  • Pictogramme des conditions météo pour le jour et la nuit.
  • Heures de lever et de coucher du soleil.
  • Température la plus haute, température la plus basse.
<?php

foreach ($days as $day)
{
    echo '<td>';
    
    $title = $day['day']['t'];
    
    echo '<img src="' . WEATHER_ICONS_URL . $day['day']['icon'] . '.png"';
    echo ' alt="' . $title . '" title="' . $title . '" />';

    $title = $day['night']['t'];

    echo '<img src="' . WEATHER_ICONS_URL . $day['night']['icon'] . '.png"';
    echo ' alt="' . $title . '" title="' . $title . '" />';

    echo '<br />';

    echo WdWeather::to24H($day['sunr']);
    echo ' &middot; ';
    echo WdWeather::to24H($day['suns']);
    
    echo '<br />';
    
    echo $day['hi'] == 'N/A' ? '&mdash;' : WdWeather::toCelsius($day['hi']) . '°C';
    echo ' &middot; ';
    echo $day['low'] == 'N/A' ? '&mdash;' : WdWeather::toCelsius($day['low']) . '°C';

    echo '</td>';
}

Et voilà, c'est fini. On remarquera juste l'utilisation de la méthode WdWeather::to24H() pour transformer la vilaine heure sur 12H en jolie heure sur 24H. On remarquera aussi l'utilisation de la méthode WdWeather::toCelsius()pour transformer les vilains degrés Fahrenheit en jolis degrés Celsius.

</tr>
</table>

Le résultat

Voici le résultat pour ce glorieux jour de soleil. Nous sommes le 19 Avril 2008, il est 12H27 et dans quelques heures le weekend va être tout trempé et morne.

Espérons que ces prévisions là soient toutes pourries :-)

WdWeather

Cadeau bonux

Pour ceux qui sont tentés, voici quelques pictogrammes pour agrémenter vos présentations. Vous en trouverez sans doute de bien mieux ailleurs, mais là vous n'avez pas à chercher ;-)

Laisser un commentaire

59 commentaires

007
007

Bonne info ! Tres bon script et bonne explication ! Continue comme ca, je t'ajoute dans mes lectures rss quodiennes

yanice
yanice

il ya une chose qui m'échappe, sur la plupart des sites proposant des tuto pour l'utilisation de weather.com, on voit des fonctions « maisons » pour convertir les degré Fahrenheit en degré Celsius, or le paramètre « unit » de l'url du xml permet de l'obtenir directement « &unit=m ». sinon, pour ce qui est de la recherche du code de la ville, comment faire pour rechercher Alger? Venise? ou même Pékin? merci

Olivier
Olivier

Salut Yanice,

Merci pour l'info concernant le paramètre « unit ». Comme tu peux peut-être t'en douter, je n'avais aucune documentation lors de la création de la classe et c'est vrai que je n'y suis pas retourné depuis.

Concernant la recherche du code de la ville, il faut peut-être utiliser son appellation Anglaise…

Olivier
Olivier

Le message d'erreur que tu rapportes est assez typique. C'est la version 4 de PHP qui interprète le code, essaie donc avec la version 5, il ne devrait pas y avoir de problème.

Tu as raison, ce serait pas mal de mettre à jour le code. Promis je m'en occupe dès qu'une mairie me demande la météo sur son site.

Olivier
Olivier

Il semblerait que le code « partenaire » soit maintenant obligatoire, ce qui n'était pas le cas auparavant… Je suis en train de décortiquer l'extension « 1-ClickWeather » de Firefox afin de trouver une solution. Sinon, vous pouvez toujours vous enregistrer :

http://www.weather.com/services/oap.html

SAMY
SAMY

Salut,

j'ai un soucis, j'ai rien qui s'affiche à l'écran, la page reste blanche.

pourtant j'ai tout fait comme toi

il me récupere le code « $code ». j'ai vu qu'il déconnait à partir de « $days = $weather->getWeather($code, 4); » et du foreach

Cordialement

Samy
Samy

Il semblerait que le code « partenaire » soit maintenant obligatoire, ce qui n'était pas le cas auparavant… Je suis en train de décortiquer l'extension « 1-ClickWeather » de Firefox afin de trouver une solution. Sinon, vous pouvez toujours vous enregistrer :

http://www.weather.com/services/oap.html

On peut meme pas s'enregistrer sur le site, le lien new user ne marche pas

yanice
yanice

ben pas de quoi :) sinon, pour l'appellation anglaise des villes, c'est ce que je me suis résolu à faire, mais disons que c'est extrêmement fastidieux et particulièrement compliqué. d'autant que toutes les villes n'ont pas de nom « anglais »; bref vous vous rendez-bien compte du boulot que ça entraîne, donc si quelqu'un trouve un jour une meilleure solution, je suis preneur!!

Fabrice
Fabrice

Bonjour, ce code à l'air pas mal mais je n'arrive pas a le faire fonctionner. Y'a t'il une personne qui pourrait faire les corrections afin qu'il fonctionne en s'enregistrant comme partenaire.

j'ai créer un page wdweather.php et j'y ai copier le code fournit « Le Code ». ensuite j'ai créé un page météo ou j'y ai mis le r este du code « L'exemple »

probleme : Parse error: syntax error, unexpected T_STATIC, expecting T_OLD_FUNCTION or T_FUNCTION or T_VAR or '}' in /homepages/29/d311675876/htdocs/wdweather.php on line 171

j'imagine que le code a du changé depuis le temps et je voulai donc savoir si il était possible de l'avoir corrigé ?

Merci à vous tous !!

soraya
soraya

merci pour le parseur  !!! je l'ai utilisé et impec. il faut cependant changer l 'url dans la finction function getWeather($city_code, $days) par 'http://xml.weather.com/weather/local/' . $city_code . '?cc=*&unit=s&dayf=' (..xml..à la place de.. xoap..)

Sinon une question: comment je peux faire pour afficher les jours ? « monday, tuesday.. »  ??

merci ;)
vive le p2p

soraya
soraya

à yanice: j'ai mis directement le code ville de type FRXXXX que tu peux trouver ici http://xoap.weather.com/search/search?where=%20paris

tu affectes ce code à la variable $code: $code = « FRXX0076 »;

hasta batata !

Pascal
Pascal

Salut, Super code, clair et précis. Mais tout comme Soraya, je n'arrive pas a récupérer le jour et la date et la mettre en francais, quelqu'un à la soluce ?

Merci à vous

Pascal

Olivier
Olivier

Le jour et la date ne font pas partie du flux XML. Pour cela, il suffit de faire une itération depuis la date d'interrogation du service :

<?php

$now = time();

for ($i = 0 ; $i < 6 ; $i++)
{
    echo "j+$i: " . date('D'strtotime("+$i day"$now)) . " <br />";
}

Pour que les jours apparaissent en français, il vous faudra paramétrer PHP en utilisant la fonction setlocale() :

<?php

setlocale(LC_TIME, 'fr_FR.UTF8''fr.UTF8');

Comme l'a suggérer Soraya, j'ai modifié le code de la fonction pour utiliser « xml. » à la place « xoap. ». On obtient les mêmes résultats, sauf que « xoap. » requiert le code partenaire que l'on obtient en s'enregistrant, ce que j'ai fais pour tirer tout ça au clair.

ba
ba

Bonjour, Script tres clair ./ Merci y'aurait il un moyen pour éviter de switcher trop vite entre les températures du jour et de la nuit? Car par exemple à 15h défois je me retrouve avec les températures basses du soir? Merci

Olivier
Olivier

Philippe,

C'est Dallas c'est histoire de météo :)

J'ai l'impression que l'affichage des erreurs est désactivé sur ton serveur. Si tu as accès au fichier de configuration de PHP (php.ini) modifie lignes suivantes :

;error_reporting = E_ALL & ~E_DEPRECATED
error_reporting = E_ALL | E_DEPRECATED | E_NOTICE | E_STRICT

;display_errors = Off
display_errors = On

Sinon, tu peux toujours ajouter les lignes suivante au début de ton script :

<?php

ini_set('display_errors'true);
error_reporting(E_ALL | E_DEPRECATED | E_NOTICE | E_STRICT);

Ainsi, tu sera averti de nombreuses erreurs, comme l'utilisation de variables non définies, ou l'accès à des clés non définies.

Concernant la météo, et particulièrement ses informations qui disparaissent, tu peux toujours les stocker dans un fichier, ou une base de données, si tu sais comment faire. La fonction serialize() te permettra de transformer l'objet en chaine de caractères pour le stocker.

Pour finir, jette un œil à la « Weather API » de Weather Underground, ça m'a l'air pas mal.

Courage !

Augras
Augras

Bonsoir,

J'ai trouvé !

En fait ton code récupère bien tout. Et c'est bien uniquement au niveau de l'affichage qu'il faut rajouter du code dans le foreach sous la forme :

<?php

echo $day['day']['hmid'] == 'N/A' ? '&mdash;' : $day['day']['hmid'] . '%';
echo ' &middot; ';
echo $day['night']['hmid'] == 'N/A' ? '&mdash;' : $day['night']['hmid'] . '%';

pour afficher par exemple le taux d'humidité.

J'ai donc modifié le code comme ci-dessous pour afficher en plus le taux d'humidité, la probabilité de précipitation, la vitesse du vent, la vitesse des rafales de vent, le paramètre « d » du vent dont je n'ai pas réussi à trouver la signification et la direction du vent :

<?php

foreach ($days as $day)
          {
          echo "<td style=\"text-align:center; width:110px\">";
                 $title = $day['day']['t'];
    
                  echo '<img src="' . WEATHER_ICONS_URL . $day['day']['icon'] . '.png"';
                  echo ' alt="' . $title . '" title="' . $title . '" />';

                  $title = $day['night']['t'];

                  echo '<img src="' . WEATHER_ICONS_URL . $day['night']['icon'] . '.png"';
                  echo ' alt="' . $title . '" title="' . $title . '" />';

                  echo '<br />';

                  echo WdWeather::to24H($day['sunr']);
                  echo ' &middot; ';
                  echo WdWeather::to24H($day['suns']);
    
                  echo '<br />';

                  echo $day['hi'] == 'N/A' ? '&mdash;' : $day['hi'] . '°C';
                  echo ' &middot; ';
                  echo $day['low'] == 'N/A' ? '&mdash;' : $day['low'] . '°C';

                  echo '<br />';

                  echo $day['day']['hmid'] == 'N/A' ? '&mdash;' : $day['day']['hmid'] . '%';
                  echo ' &middot; ';
                  echo $day['night']['hmid'] == 'N/A' ? '&mdash;' : $day['night']['hmid'] . '%';

                  echo '<br />';

                  echo $day['day']['ppcp'] == 'N/A' ? '&mdash;' : $day['day']['ppcp'] . '%';
                  echo ' &middot; ';
                  echo $day['night']['ppcp'] == 'N/A' ? '&mdash;' : $day['night']['ppcp'] . '%';

                  echo '<br />';

                  echo $day['day']['wind']['s'] == 'N/A' ? '&mdash;' : $day['day']['wind']['s'] . '';
                  echo ' &middot; ';
                  echo $day['night']['wind']['s'] == 'N/A' ? '&mdash;' : $day['night']['wind']['s'] . '';

                  echo '<br />';

                  echo $day['day']['wind']['gust'] == 'N/A' ? '&mdash;' : $days['day']['wind']['gust'] . '';
                  echo ' &middot; ';
                  echo $day['night']['wind']['gust'] == 'N/A' ? '&mdash;' : $days['night']['wind']['gust'] . '';

                  echo '<br />';

                  echo $day['day']['wind']['d'] == 'N/A' ? '&mdash;' : $days['day']['wind']['d'];
                  echo ' &middot; ';
                  echo $day['night']['wind']['d'] == 'N/A' ? '&mdash;' : $days['night']['wind']['d'];

                  echo '<br />';

                  echo $day['day']['wind']['t'] == 'N/A' ? '&mdash;' : $days['day']['wind']['t'];
                  echo ' &middot; ';
                  echo $day['night']['wind']['t'] == 'N/A' ? '&mdash;' : $days['night']['wind']['t'];

                  echo '<br />';

              }

Ça fonctionne parfaitement pour les 3 premiers y compris la vitesse du vent. Pour les rafales le flux xml étant très souvent à N/A je ne sais pas si ça fonctionne pour afficher les valeurs mais le N/A est bien pris en compte. Là où je ne comprends pas, encore une fois, c'est que je n'ai rien d'affiché pour le paramètre « d » du vent et la direction du vent… sauf quand les valeurs sont N/A où j'ai un trait comme à chaque fois qu'une valeur est N/A. Ça ne doit pas être grand chose à trouver mais je n'ai pas réussi à mettre le doigt dessus.

Le code ci-dessous me permet d'afficher les valeurs du jour, elles ne sont pas dans le flux xml pour les jours suivants, pour la température courante, la température ressentie, la pression atmosphérique, la visibilité, l'indice uv et le point de rosée :

<?php

$xml = file_get_contents
(
    'http://xml.weather.com/weather/local/' . $code . '?cc=*&unit=m'
);

if (!$xml)
{
    return;
}

$tree = simplexml_load_string($xml);

echo '<b>ressentie</b> de <b>' . $tree->cc->flik . '°C</b>.<br>';
//fin t° ressentie
if (!$xml)
{
    return;
}

$tree = simplexml_load_string($xml);

echo ' La <b>pression</b> atmosphérique est de <b>' . $tree->cc->bar->r . ' mb</b>.<br>';

if (!$xml)
{
    return;
}

$tree = simplexml_load_string($xml);

echo ' La <b>visibilité</b> est à <b>' . $tree->cc->vis . ' km</b>.<br>';

if (!$xml)
{
    return;
}

$tree = simplexml_load_string($xml);

echo ' L\'indice <b>UV</b> est de <b>' . $tree->cc->uv->i . '/5</b>.<br>';

if (!$xml)
{
    return;
}

$tree = simplexml_load_string($xml);

echo ' Le <b>point de rosée</b> est à <b>' . $tree->cc->dewp . '°C</b>.<br>';

J'arrive donc à ce que je voulais au départ : reste à solutionner cette histoire d'affichage pour certains paramètres du vent etl a question des valeurs du jour qui passent à N/A entre 14 et 15h qui reste entière et donc la façon de continuer à afficher ces valeurs toujours à déterminer.

Merci encore pour ton travail. Si tu as la solution pour ce qui reste je suis preneur car pour le coup je sèche.

Philippe

Fethi
Fethi

BRAVO; Simple, bien expliqué (u r a teacher) et opérationnel sans bugs

augras
augras

Bonjour Olivier,

Je ne lâche pas l'affaire mais j'ai posté il y a environ 15 jours une réponse que tu n'as manifestement pas vue (il y a eu un message d'erreur, j'ai reposté dans la foulée…) : je reproduis en gros le message.

J'ai bien compris ce que faisait la fonction preg_match() et je pensais que ton code ci_dessous faisait le travail : preg_match ( '#' .

        '<icon>' . $mc . '</icon>\s*' .//icônes
        '<t>' . $mc . '</t>\s*' .//tendance : ensoleillé/nuageux... le jour
        '<wind>(.*)</wind>\s*' .//vent
        '<bt>' . $mc . '</bt>\s*' .//tendance : ensoleillé/nuageux... la nuit
        '<ppcp>' . $mc . '</ppcp>\s*' .//risque de précipitations
        '<hmid>' . $mc . '</hmid>' .//taux d'humidité

        '#ms',

        $xml, $matches
    );

C'est ton code tel quel avec simplement en remarque la signification de ce qui est recherché. Donc pas de clés rajoutés ici.

Ensuite je pensais que rajouter un code similaire au tient permettrait leur affichage : echo $day['ppcp'] == 'N/A' ? '—' : $day['ppcp'] . '%'; echo ' · '; echo $day['ppcp'] == 'N/A' ? '—' : $day['ppcp'] . '%'; Sauf que c'est vide !

Effectivement si le résultat est N/A il n'y a rien d'affiché, sinon c'est la valeur relevée et s'il y a zéro au lieu de N/A et bien il devrait y avoir zéro d'affiché car il constitue une valeur. En ce moment, dimanche 7 octobre à 14h30 pour les 4 jours à venir toutes les valeurs ont soit N/A soit une valeur différente de zéro et mon affichage est vide pour aujourd'hui et les 4 jours suivants alors que la majorité des clés a des valeurs !

J'ai remarqué également que la T° maximale de la journée disparaissait dans l'après-midi : là par exemple il est indiqué N/A et donc elle n'est plus affichée. Et c'est le cas pour beaucoup de données concernant la journée en cours. Je ne sais pas d'où cela peut venir mais pour éviter cette perte de données est-ce qu'il y aurait la possibilité de stocker les dernières données disponibles du jour afin de les reprendre quand le flux xml affiche N/A ?

Merci encore.

Philippe

Olivier
Olivier

La fonction preg_match() qui se trouve avant la function array_combine() est utilisée pour extraire de la chaine XML les valeurs qui nous intéressent, c'est pourquoi, si tu rajoute des clés, il faut également étendre l'expression rationnelle pour extraire leur valeur.

En ce qui concerne les valeurs vides j'ai l'impression que c'est normal. En regardant le flux XML les valeurs ppcp sont toutes à zéro. Dans ton code, tu vérifies si ppcp est égal à N/A, je ne pense pas que cela soir correct. Effectivement, certaines propriétés peuvent avoir la valeur N/A, mais ce n'est pas un généralité. Regarde le code XML pour te faire une idée.

Bioslord
Bioslord

Hello, très bien ce parseur :) Ya moyen d'afficher la température actuel ? Elle se trouvait dans : 59 mais le script ne parse que les < day> …

Bioslord
Bioslord

Bou !! Le code ne s'affiche pas ^^ je recommence , elle s'affiche dans

<cc> <blabla> <tmp>59</tmp> <blaba> </cc>

faut attendre 3 minute en plus …

Olivier
Olivier

Salut Bioslord,

Effectivement, la température courante se trouve dans <cc><tmp> et à ce que je vois elle est en degrés Fahrenheit.

J'ai un peu honte de revoir cette classe, il faut dire qu'elle avait été faite pour PHP4 et que je ne m'en suis jamais servi depuis. Bref, je te conseille d'utiliser la fonction simplexml_load_string() pour traduire le texte XML en arbre d'objets, tu pourras ainsi accéder tout simplement aux champs qui t'intéressent.

Voici un exemple pour la température courante :

<?php

$city_code = 'FRXX0099'// Le code pour Toulouse

$xml = file_get_contents
(
    'http://xml.weather.com/weather/local/' . $city_code . '?cc=*&unit=s'
);

if (!$xml)
{
    return;
}

$tree = simplexml_load_string($xml);

echo 'Température courrante à <em>' . $tree->loc->dnam . '</em>&nbsp;: ' . WdWeather::toCelsius($tree->cc->tmp);

J'espère que ça répond à ta question.

PS: Mets ton code entre apostrophes inversées (`) pour qu'il s'affiche correctement. Les messages sont transformés par Markdown, puis filtrés, c'est pour cela que les balises bizarres disparaissent.

Vince
Vince

Ah chouette classe :)

Par contre ton pack d'icone n'est plus disponible :( possibilité de le remettre ? :)

Olivier
Olivier

Puisque tu le demandes gentillement le voici : quelques pictos

Jean
Jean

Bonjour,

Ce script à l'air sympa, mais comment fait-on pour savoir à quoi correspondent les chiffres? L'icone de gauche représente la météo du jour? du lendemain? 7.05 et 20° sa veut dire qu'il fesait 20° à 7j le matin et qu'il fera 9° à 20h 43 ?

Olivier
Olivier

Les informations que l'on obtient sont pour le jour en cours et les suivants.

« 7:05 • 20:43 » sont les heures de lever et de coucher du soleil. « 20°C • 9°C » sont les températures maximales et minimales (sans doute la nuit).

Tu peux modifier le script pour le mettre à ton goût.

Vince
Vince

Merci :) Dans l'urgence je suis aller en chercher d'autre :D

Olivier
Olivier

@ranell: Les prévisions par heures ne sont pas disponibles dans le flux, mais peut-être dans un autre ?

LynX
LynX

Ok je regarde tout ça ! Merci Olivier pour toutes ces infos.

LynX
LynX

C'est exact mais cela ne donne pas les prévisions sur plusieurs jours comme au paravant… Dommage.

Olivier
Olivier

Pour obtenir les prévisions météo pour les jours à venir il suffit d'ajouter le paramètre dayf (pour « day forcast » j'imagine) : http://xml.weather.com/weather/local/FRXX0099?cc=*&unit=s&dayf=5

LynX
LynX

Bah !! Suis-je bête… En gros c'est exactement comme avant sans l'identification qui était nécessaire. Je ne comprends pas trop à quoi joue Weather chanel… Merci Olivier PS : Tu parlais d'applis pour mobile auxquelles pensais-tu en particulier ?

Olivier
Olivier

Sur mon Galaxy SII j'utilise 3D Digital Weather, un widget gratuit parmi tant d'autres. Je ne sais pas s'il utilise weather channel (le code ville est le même en tout cas), mais il doit bien récupérer ses informations quelque part. Peut-être qu'il utilise une licence unique mais ça me parait peu probable.

météo gratuite
météo gratuite

Un site utilisant weather : http://www.the-meteo.com . Je trouve ce site pas mal, il est clair et en plus il y a une actualité météo .

Qu'en pensez vous ??

julien
julien

Maintenant le site weather est devenu payant, du coup tous les script météo gratuits sont HS …

Olivier
Olivier

Cela fonctionne toujours, voici par exemple le temps actuel pour toulouse: http://xml.weather.com/weather/local/FRXX0099?cc=*&unit=s. Avec toutes les applis gratuites qui donnent la météo sur mobiles je crois qu'on est tranquille.

ranell
ranell

Bonsoir :) Merci pour ce code :) C'est possible de récupérer les prévisions heures par heures? je m'y perds un peu :S Sinon j'ai testé le code il fonctionne à merveille :)

augras
augras

Bonjour,

Tout d'abord bravo et merci pour ce code. Tout fonctionne bien mais comme je suis gourmand je veux plus de paramètres affichés ! Je suis donc allé voir ce qu'affiche la page : http://xml.weather.com/weather/local/FRXX0099?cc=*&unit=s&dayf=5 et d'autres paramètres sont disponibles et m'intéressent. Par exemple tmp pout le T° courante, flik pour la T° ressentie, r pour la pression atmosphérique, hmid pour le % d'humidité, vis pour la visibilité, uv pour l'indice uv, dewp pour le point de rosée. Mais mon niveau en développement étant quasi nul je ne réussi pas à récupérer ces paramètres ! Pour l'affichage ça semble ok mais c'est vide vu que je ne récupère pas. J'ai rajouté par exemple

<?php

function parseDay($xml)
    {
        $mc = $this->markup_contents;
    
        preg_match
        (
            '#' .
            
        '<tmp>' . $mc . '</tmp>\s*' .//T°actuelle
        '<flik>' . $mc . '</flik>\s*' .//T°ressentie
            '<hi>' . $mc . '</hi>\s*' .//T°max
            '<low>' . $mc . '</low>\s*' .//T°min
            '<sunr>' . $mc . '</sunr>\s*' .//levé du soleil
            '<suns>' . $mc . '</suns>\s*' .//couché du soleil
            '<part p="d">(.*)</part>\s*' .//journée
            '<part p="n">(.*)</part>' .//nuit
            
            '#ms',
            
            $xml$matches
        );
        
        array_shift($matches);
                    
        #
        # parse day periods (day / night)
        #
        
        $matches[4] = $this->parseDayPeriod($matches[4]);
        $matches[5] = $this->parseDayPeriod($matches[5]);
        
        #
        #
        #
        
        return array_combine
        (
            array('tmp''flik''hi''low''sunr''suns''day''night')$matches
        );
    }

Mais j'obtiens l'erreur Warning: array_combine(): Both parameters should have an equal number of elements in xxxxxchemin d'accès à mon fichier .php line 126 Là je bloque !

J'aimerai également afficher la probabilité de précipitation mais n'ai pas trouvé la correspondance : peut-être ppcp que je n'ai pas identifié. Je n'ai pas compris non plus le paramètre bt, gust et t pour le vent. Ca fait beaucoup de choses mais si quelqu'un peut m'aider je suis bien entendu preneur.

Merci.

augras
augras

Bonsoir Olivier, Et merci de continuer à suivre ces commentaires. Le développement c'est pas mon truc mais jusqu'à maintenant j'ai toujours réussi à faire ce que je voulais, qui restait somme toute très limité. J'ai trouvé sur le net effectivement que array_combine fonctionne comme tu l'indiques. Par contre je n'ai visiblement pas compris dans ton code ce qu'étais ces 2 tableaux ! Le premier, les clés, est pour moi constitué de ça par exemple : array('hi', 'low', 'sunr', 'suns', 'day', 'night') ; et le deuxième, les valeurs par $matches. Et manifestement je n'arrive pas à faire correspondre les deux ! Autant pour les clés c'est simple : je rajoute les lignes telles que mis dans mon post ci-dessus. Autant je n'arrive pas à alimenter $matches  : car je n'ai pas compris comment il était fabriqué. C'est certainement comme le nez au milieu du visage mais pour le moment je ne le trouve pas ce fichu nez !

Olivier
Olivier

array_combine() permet de créer un tableau à partir de deux tableaux : un qui définit les clés et un autre qui définit les valeurs. La fonction râle si le nombre de clés et le nombre de valeurs ne coïncident pas.

Franchement j'ai un peu honte de ce script. Je l'avais fais pour PHP4, et depuis il y a SimpleXML qui permet de se passer de toutes ces vilains expression régulières.

Si ça peut dépanner, je fournirai prochainement une version mise à jour.

augras
augras

C'est encore moi ! En fait un certain nombre de données ne sont pas disponibles en prévision mais seulement pour la date du jour : tmp, flick, r, vis, uv et dewp. Ces données je les récupère et les affiche sans problème avec un code de ce type :

<?php

if (!$xml)
{
    return;
}

$tree = simplexml_load_string($xml);

echo ' La <b>pression</b> atmosphérique est de <b>' . $tree->cc->bar->r . ' mb</b>.<br>';

Pour les données restantes, accessibles dans la page xml de weather.com en prévisions (hmid, ppcp et wind) tu as déjà tout prévu dans ton code… me reste plus qu'à les mettre dans la boucle d'affichage. J'ai rajouté dans le foreach des lignes de ce genre :

<?php

echo $day['ppcp'] == 'N/A' ? '&mdash;' : $day['ppcp'] . '%';
echo ' &middot; ';
echo $day['ppcp'] == 'N/A' ? '&mdash;' : $day['ppcp'] . '%';

Les lignes apparaissent bien mais vident de données alors que les données sont bien disponibles pour le jour et la nuit et que, si j'ai bien compris le code, tout est bien récupéré.

Ma compréhension du code étant relativement limités… qu'est-ce que j'ai raté ?

augras
augras

Bonjour, C'est encore moi ! Les paramètres du vent s'affiche parfaitement comme le reste… quand il n'y a pas de faute dans le code.

J'avais mis :

<?php

echo $day['day']['wind']['d'] == 'N/A' ? 'N/D' : $days['day']['wind']['d'];

echo ' | ';

echo $day['night']['wind']['d'] == 'N/A' ? 'N/D' : $days['night']['wind']['d'];

alors que le bon code est :

<?php

echo $day['day']['wind']['d'] == 'N/A' ? 'N/D' : $day['day']['wind']['d'];

echo ' | ';

echo $day['night']['wind']['d'] == 'N/A' ? 'N/D' : $day['night']['wind']['d'];

C'est $day et non $days !
J'en ai profité pour faire afficher N/D au lieu de __ et le pipe en séparateur au lieu du point.

Maintenant reste ce problème de disparition des données du jour en début d'après-midi.

Philippe

augras
augras

Merci de ta réponse.

Pour les erreurs php je vais insérer le code que tu indiques dans mon script.

Pour la disparition des données prématurément il s'agit bien d'un problème de décalage horaire… aux États-Unis ils sont en avance sur nous !

Je sais récupérer les données : il « suffit » donc que avant d'afficher une donnée je vérifie si elle est à N/A ou pas ; si non je stocke dans un fichier et si oui j'affiche alors la donnée du fichier. Voilà la théorie…

Merci pour weather undergroud mais pour le moment je vais continuer à jouer avec weather.com.

Quand j'aurai réussi à passer outre la disparition des données je viendrai donner le code pour ceux que ça intéresse…ça sera pas pour tout de suite !

Philippe

Hugo
Hugo

Voila mon script pour afficher les jours en français, à mettre dans foreach ($days as $day) :

<?php

$i=0;
$now = time();
$frdate = date('D'strtotime("+$i day"$now));
 switch ($frdate) {
    case "Mon":
        echo "Lundi <br />";
    break;
    case "Sun":
        echo "Dimanche <br />";
    break;
    case "Tue":
        echo "Mardi <br />";
    break;
    case "Wed":
        echo "Mercredi <br />";
    break;
    case "Thu":
        echo "Jeudi <br />";
    break;
    case "Fri":
        echo "Vendredi <br />";
    break;
    case "Sat":
        echo "Samedi <br />";
    break;  
}
$i++;
Olivier
Olivier

@Hugo: Utilise plutôt la fonction strftime(), elle est localisée. Regarde l'exemple 1.

Fabrice
Fabrice

Bonjour, j’essaie de mettre en place la météo en suivant le code que vous proposez (pas d'inscription à weather comme dit dans le 1ers commentaires et sa fonctionne… c'est normal ?). Jusqu’à présent sa fonctionne mais je n'ai pas les icônes qui s'affichent. (j'ai pourtant bien mis les icônes au bon endroit et le bon répertoire) De plus j'aimerai avoir les jours au dessus de chaque météo afin que l'internaute sache de quel jour il sagit (j'ai essayé le code du hugo mais il me ressort que des dimanche (c'est aujourd'hui)).

Olivier
Olivier

@Fabrice: C'est bon, tu as réussi à faire ce que tu voulais ?

Fabrice
Fabrice

Pour les icônes c'est bon sa fonctionne (dans un pack les icônes s'appellent 1.png, 2.png… au lie de 01.png, 02.png… ou inversement )

Pour la date des jours en fr j'ai juste modifié un peu ton code :

<?php

setlocale(LC_TIME, 'fr_FR.UTF-8')$now = time();
for ($i = 0 ; $i < 4 ; $i++)
{
    echo '<td>';
    echo strftime('%A %e %B %Y 'strtotime("+$i day"$now)) . " <br />";
    echo '</td>';
}
Olivier
Olivier

@Noritaka: Il est possible que l'ouverture des URL soit désactivée sur le serveur Free. Tu peux le vérifier en faisant un phpinfo(). La directive allow_url_fopen doit être vraie.

Si tu ne peux pas utiliser file_get_contents() avec une URL, tu peux par exemple modifier le code pour utiliser cURL à la place, en espérant que l'extension soit activée sur le serveur Free :

<?php

$ch = curl_init($url);

curl_setopt(CURLOPT_RETURNTRANSFER, true);

// exécution de la session
curl_exec($ch);

// fermeture des ressources
curl_close($ch);
Noritaka
Noritaka

Bonjour,

ce code est exactement ce que je cherchais, le problème est que je n'arrive pas à le faire fonctionner. Je suis sur Free (je ne sais pas si ça change quelque chose), et toutes les fonctions « file_get_contents » ne me renvoient rien. Du coup les variables $xml ont NULL. j'ai regardé le lien dans la fonction file_get_contents, il est correcte et renvoie bien des données. Mais cette fonctionne semble ne pas réussir à les récupérer et les mettre dans les variables xml. Que puis-je faire ? Help please.

Merci

Noritaka
Noritaka

Bonjour,

merci beaucoup pour ta réponse. Il semblerait (selon des forums) que Free bloque le file_get_contents, et pourtant dans phpinfo j'ai allow url fopen on(Local Value) on(Master Value). Je pense que c'est bloqué pour les liens extérieurs. j'avais déjà vu le curl sur certain forum (si je te contacte c'est justement parce que je n'ai rien trouvé, et je suis perdu), mais ça me renvoie null. Voici ce que j'ai mis :

<?php

$url="http://xml.weather.com/weather/local/FRXX0099?cc=*&unit=s&dayf=4";
$ch = curl_init($url);
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);  
curl_exec($ch);   
var_dump(curl_exec($ch));   
curl_close($ch);

Cela me renvoie bool(false).

D'autres idées ? Personne n'a de pages sur Free ? Quel type d'hébergeur gratuit utilisez vous ? Merci d'avance

Olivier
Olivier

J'ai oublié de mettre le retour de la fonction dans une variable :( Voici la correction :

<?php

$ch = curl_init($url);

curl_setopt(CURLOPT_RETURNTRANSFER, true);

// exécution de la session
$xml = curl_exec($ch);

// fermeture des ressources
curl_close($ch);

var_dump($xml);
Noritaka
Noritaka

Bonjour,

merci encore pour ta réponse. Il manque aussi $ch dans la fonction curl_setopt. Mais cela ne fonctionne toujours pas. Je pense qu'il n'est pas possible de rapatrier quoi que ce soit de l'extérieur avec les pages perso de free. C'est vraiment contraignant car on ne peut faire appel à aucune API extérieure. j'ai même essayé avec wget, mais cela ne ramène rien. Quelqu'un a déjà eu ce problème ? Une idée pour le résoudre ? Quel dommage, j'aurai tellement voulu avoir ce bout de code dans mes pages…. :(

Aurel
Aurel

Bonjour,

ce script est vraiment bien, je l'ai passé en affichage colonne mais je ne trouve pas comment y insérer le jour sur chaque lignes. Si vous pouviez m'aider sur ce point?

Merci d'avance

Olivier
Olivier

Merci. Regarde mon commentaire concernant le nom des jours, tu devrais t'en sortir avec ça.

Olivier
Olivier

@Aurel : Jette un oeil au commentaire de Fabrice la ligne echo strftime(… affiche une date formatée pour le jour du for().

@ROUSber : Lorsque j'ai écris ce script, je bossais dans une agence qui faisait pas mal de site de mairie. Depuis je n'ai pas eu l'occasion de le réutiliser, du coup il est resté en l'état. Si tu es nouveau à PHP c'est l'occasion parfaite de mettre les mains dans le cambouis ! Essai donc de te débrouiller et si tu coinces laisse-moi un commentaire.

ROUSber
ROUSber

Bonjour, Olivier, C'est avec un très grand intérêt que j'ai parcouru ce blog, afin de trouver une source d'inspiration, pour une page, purement perso, que j'essaye de réaliser. Dans cette page, je souhaiterai y inclure un genre de petit widget, pour afficher la météo dans le secteur ou j'habite (FRXX0276 Saint-Quentin, 02, France). Ne trouvant rien de bien intéressant sur le net, j'en revient à dire, que l'on est jamais si bien servi que par soi-même, d'ou ma démarche. A un moment, tu parles de remettre à jour ton code, en y incluant, je suppose, toutes les modifications et remarques faites. Quand est-il, justement de cette mise à jour, car je serai, comme d'autres, je pense, intéressé. En attendant, je te remercie de l'aide que tu apportes, ainsi que d'autres, aux personnes n'ayant pas votre savoir (et patience). Bien cordialement, Bernard

Jean Claude
Jean Claude

Bonjour Olivier, J'ai découvert ce sript que je trouve excellent. Je l'utilise pour un développement web en cours d'une mairie. Je suis confronté à un problème déjà évoqué dont je n'ai pas vu de réponse, sauf erreur de ma part. Il s'agit des erreurs Notice: Undefined offset: 2 in C:\wamp\www\test\meteo\index.php on line 38, et, Warning: array_combine() [function.array-combine]: Both parameters should have an equal number of elements in C:\wamp\www\test\meteo\index.php on line 45 dont j'ai cerné le problème. En fait il s'agit d'un manquement de champs de balise du flux provenant de weather.com. seulement sur le jour 0 c'est à dire aujourd'hui. (ex: champs de la balise ou , etc… toujours sur le day d=« 0 »). Avez-vous déjà constaté ce manquement? Avez-vous trouvé une solution? Il est impossible d'utiliser ce parse avec une garantie à 100%. D'avance merci, Très cordialement, JC

laul
laul

voici une proposition avec quelques mis à jours https://github.com/llaull/php-module-meteo