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:
- On demande le code de la ville dont on souhaite connaitre les prévisions météo.
- On demande les prévisions météo pour les jours à venir.
- 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 :
- On crée l'objet.
- On récupère le code de la ville qui nous intéresse. Ici Toulouse, parce que c'est chez moi.
- 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($code, 4);
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 ' · ';
echo WdWeather::to24H($day['suns']);
echo '<br />';
echo $day['hi'] == 'N/A' ? '—' : WdWeather::toCelsius($day['hi']) . '°C';
echo ' · ';
echo $day['low'] == 'N/A' ? '—' : 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 :-)

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 ;-)
007
Bonne info ! Tres bon script et bonne explication ! Continue comme ca, je t'ajoute dans mes lectures rss quodiennes
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
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…
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
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
On peut meme pas s'enregistrer sur le site, le lien new user ne marche pas
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!!
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
à 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 !
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 !!
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.
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
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 :
Pour que les jours apparaissent en français, il vous faudra paramétrer PHP en utilisant la fonction
setlocale():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
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
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
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
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 :
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.
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
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
Ah chouette classe :)
Par contre ton pack d'icone n'est plus disponible :( possibilité de le remettre ? :)
Olivier
Puisque tu le demandes gentillement le voici : quelques pictos
Vince
Merci :) Dans l'urgence je suis aller en chercher d'autre :D
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
Maintenant le site weather est devenu payant, du coup tous les script météo gratuits sont HS …
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.
LynX
C'est exact mais cela ne donne pas les prévisions sur plusieurs jours comme au paravant… Dommage.
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=5LynX
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
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.
LynX
Ok je regarde tout ça ! Merci Olivier pour toutes ces infos.