diff --git a/Example_Cache.php b/Example_Cache.php
new file mode 100644
index 0000000..d8d0198
--- /dev/null
+++ b/Example_Cache.php
@@ -0,0 +1,18 @@
+getWeather('Berlin', $units, $lang);
+echo "EXAMPLE 1
\n\n\n";
+echo $weather->temperature;
diff --git a/Examples.php b/Examples.php
index e810bd2..e55c1bc 100644
--- a/Examples.php
+++ b/Examples.php
@@ -14,8 +14,10 @@
* @see http://openweathermap.org/appid
*/
-// Include api class
-require_once('OpenWeatherMap.php');
+use cmfcmf\OpenWeatherMap;
+use cmfcmf\OpenWeatherMap\Exception as OWMException;
+
+require('cmfcmf/OpenWeatherMap.php');
// Language of data (try your own language here!):
$lang = 'de';
@@ -23,8 +25,11 @@
// Units (can be 'metric' or 'imperial' [default]):
$units = 'metric';
+// Get OpenWeatherMap object. Don't use caching (take a look into Example_Cache.php to see how it works).
+$owm = new OpenWeatherMap();
+
// Example 1: Get current temperature in Berlin.
-$weather = OpenWeatherMap::getWeather('Berlin', $units, $lang);
+$weather = $owm->getWeather('Berlin', $units, $lang);
echo "EXAMPLE 1
\n\n\n";
// $weather contains all available weather information for Berlin.
@@ -73,7 +78,7 @@
echo "
\n";
// Example 2: Get current pressure and humidity in Hongkong.
-$weather = OpenWeatherMap::getWeather('Hongkong', $units, $lang);
+$weather = $owm->getWeather('Hongkong', $units, $lang);
echo "
\n\n\nEXAMPLE 2
\n\n\n";
/**
@@ -98,14 +103,14 @@
echo "
\n";
// Example 4: Get current temperature from coordinates (Greenland :-) ).
-$weather = OpenWeatherMap::getWeather(array('lat' => 77.73038, 'lon' => 41.89604), $units, $lang);
+$weather = $owm->getWeather(array('lat' => 77.73038, 'lon' => 41.89604), $units, $lang);
echo "
\n\n\nEXAMPLE 4
\n\n\n";
echo "Temperature: " . $weather->temperature;
echo "
\n";
// Example 5: Get current temperature from city id. The city is an internal id used by OpenWeatherMap. See example 6 too.
-$weather = OpenWeatherMap::getWeather(2172797, $units, $lang);
+$weather = $owm->getWeather(2172797, $units, $lang);
echo "
\n\n\nEXAMPLE 5
\n\n\n";
echo "City: " . $weather->city->name;
@@ -115,7 +120,7 @@
echo "
\n";
// Example 6: Get information about a city.
-$weather = OpenWeatherMap::getWeather('Paris', $units, $lang);
+$weather = $owm->getWeather('Paris', $units, $lang);
echo "
\n\n\nEXAMPLE 6
\n\n\n";
echo "Id: " . $weather->city->id;
@@ -174,19 +179,19 @@
// Example 11: Get raw xml data.
echo "
\n\n\nEXAMPLE 11
\n\n\n";
-echo "" . htmlspecialchars(OpenWeatherMap::getRawData('Berlin', $units, $lang, null, 'xml')) . "
";
+echo "" . htmlspecialchars($owm->getRawData('Berlin', $units, $lang, null, 'xml')) . "
";
echo "
\n";
// Example 12: Get raw json data.
echo "
\n\n\nEXAMPLE 12
\n\n\n";
-echo "" . htmlspecialchars(OpenWeatherMap::getRawData('Berlin', $units, $lang, null, 'json')) . "
";
+echo "" . htmlspecialchars($owm->getRawData('Berlin', $units, $lang, null, 'json')) . "
";
echo "
\n";
// Example 13: Get raw html data.
echo "
\n\n\nEXAMPLE 13
\n\n\n";
-echo OpenWeatherMap::getRawData('Berlin', $units, $lang, null, 'html');
+echo $owm->getRawData('Berlin', $units, $lang, null, 'html');
echo "
\n";
// Example 14: Error handling.
@@ -194,32 +199,32 @@
// Try wrong city name.
try {
- $weather = OpenWeatherMap::getWeather("ThisCityNameIsNotValidAndDoesNotExist", $units, $lang);
-} catch(OpenWeatherMap_Exception $e) {
+ $weather = $owm->getWeather("ThisCityNameIsNotValidAndDoesNotExist", $units, $lang);
+} catch(OWMException $e) {
echo $e->getMessage() . ' (Code ' . $e->getCode() . ').';
echo "
\n";
}
// Try invalid $query.
try {
- $weather = OpenWeatherMap::getWeather(new DateTime('now'), $units, $lang);
-} catch(Exception $e) {
+ $weather = $owm->getWeather(new \DateTime('now'), $units, $lang);
+} catch(\Exception $e) {
echo $e->getMessage() . ' (Code ' . $e->getCode() . ').';
echo "
\n";
}
// Full error handling would look like this:
try {
- $weather = OpenWeatherMap::getWeather(-1, $units, $lang);
-} catch(OpenWeatherMap_Exception $e) {
+ $weather = $owm->getWeather(-1, $units, $lang);
+} catch(OWMException $e) {
echo 'OpenWeatherMap exception: ' . $e->getMessage() . ' (Code ' . $e->getCode() . ').';
echo "
\n";
-} catch(Exception $e) {
+} catch(\Exception $e) {
echo 'General exception: ' . $e->getMessage() . ' (Code ' . $e->getCode() . ').';
echo "
\n";
}
// Example 15: Using an api key:
-# OpenWeatherMap::getWeather('Berlin', $units, $lang, 'Your-Api-Key-Here');
-# OpenWeatherMap::getRawData('Berlin', $units, $lang, 'Your-Api-Key-Here', 'json');
+# $owm->getWeather('Berlin', $units, $lang, 'Your-Api-Key-Here');
+# $owm->getRawData('Berlin', $units, $lang, 'Your-Api-Key-Here', 'json');
diff --git a/Util.php b/Util.php
deleted file mode 100644
index 89880f3..0000000
--- a/Util.php
+++ /dev/null
@@ -1,271 +0,0 @@
-OpenWeatherMap.org";
-
- public function __construct($query, $units = 'imperial', $lang = 'en', $appid = '')
- {
- // Disable default error handling of SimpleXML (Do not throw E_WARNINGs).
- libxml_use_internal_errors(true);
- libxml_clear_errors();
-
- $answer = OpenWeatherMap::getRawData($query, $units, $lang, $appid, 'xml');
- if ($answer === false) {
- // $query has the wrong format, throw error.
- throw new Exception('Error: $query has the wrong format. See the documentation of OpenWeatherMap::getRawData() to read about valid formats.');
- }
-
- try {
- $xml = new SimpleXMLElement($answer);
- } catch(Exception $e) {
- // Invalid xml format. This happens in case OpenWeatherMap returns an error.
- // OpenWeatherMap always uses json for errors, even if one specifies xml as format.
- $error = json_decode($answer, true);
- if (isset($error['message'])) {
- throw new OpenWeatherMap_Exception($error['message'], $error['cod']);
- } else {
- throw new OpenWeatherMap_Exception('Unknown fatal error: OpenWeatherMap returned the following json object: ' . print_r($error));
- }
- }
-
- $this->city = new _City($xml->city['id'], $xml->city['name'], $xml->city->coord['lon'], $xml->city->coord['lat'], $xml->city->country);
- $this->temperature = new _Temperature(new _Unit($xml->temperature['value'], $xml->temperature['unit']), new _Unit($xml->temperature['min'], $xml->temperature['unit']), new _Unit($xml->temperature['max'], $xml->temperature['unit']));
- $this->humidity = new _Unit($xml->humidity['value'], $xml->humidity['unit']);
- $this->pressure = new _Unit($xml->pressure['value'], $xml->pressure['unit']);
-
-
- // This is kind of a hack, because the units are missing in the xml document.
- if ($units == 'metric') {
- $windSpeedUnit = 'm/s';
- } else {
- $windSpeedUnit = 'mph';
- }
- $this->wind = new _Wind(new _Unit($xml->wind->speed['value'], $windSpeedUnit, $xml->wind->speed['name']), new _Unit($xml->wind->direction['value'], $xml->wind->direction['code'], $xml->wind->direction['name']));
-
-
- $this->clouds = new _Unit($xml->clouds['value'], null, $xml->clouds['name']);
- $this->precipitation = new _Unit($xml->precipitation['value'], $xml->precipitation['unit'], $xml->precipitation['mode']);
- $this->sun = new _Sun(new DateTime($xml->city->sun['rise']), new DateTime($xml->city->sun['set']));
- $this->weather = new _Weather($xml->weather['number'], $xml->weather['value'], $xml->weather['icon']);
- $this->lastUpdate = new DateTime($xml->lastupdate['value']);
- }
-}
-
-/**
- * @class General class for each value.
- */
-class _Unit
-{
- private $value;
-
- private $unit;
-
- private $description;
-
- public function __construct($value = 0.0, $unit = "", $description = "")
- {
- $this->value = (float)$value;
- $this->unit = (string)$unit;
- $this->description = (string)$description;
- }
-
- public function __toString()
- {
- return $this->getFormatted();
- }
-
- public function getUnit()
- {
- // Units are inconsistent. Only celsius and kelvin are not abbreviated. This check fixes that.
- if ($this->unit == 'celsius') {
- return '°C';
- } else if ($this->unit == 'kelvin') {
- return 'K';
- } else {
- return $this->unit;
- }
- }
-
- public function getValue()
- {
- return $this->value;
- }
-
- public function getDescription()
- {
- return $this->description;
- }
-
- public function getFormatted()
- {
- if ($this->getUnit() != "") {
- return "{$this->getValue()} {$this->getUnit()}";
- } else {
- return "{$this->getValue()}";
- }
- }
-}
-
-class _Temperature
-{
- public $now;
-
- public $min;
-
- public $max;
-
- public function __construct(_Unit $now, _Unit $min, _Unit $max)
- {
- $this->now = $now;
- $this->min = $min;
- $this->max = $max;
- }
-
- public function __toString()
- {
- return $this->now->__toString();
- }
-
- public function getUnit()
- {
- return $this->now->getUnit();
- }
-
- public function getValue()
- {
- return $this->now->getValue();
- }
-
- public function getDescription()
- {
- return $this->now->getDescription();
- }
-
- public function getFormatted()
- {
- return $this->now->getFormatted();
- }
-}
-
-class _Wind
-{
- public $speed;
-
- public $direction;
-
- public function __construct(_Unit $speed, _Unit $direction)
- {
- $this->speed = $speed;
- $this->direction = $direction;
- }
-}
-
-class _Sun
-{
- public $rise;
-
- public $set;
-
- public function __construct(DateTime $rise, DateTime $set)
- {
- $this->rise = $rise;
- $this->set = $set;
- }
-}
-
-class _City
-{
- public $id;
-
- public $name;
-
- public $lon;
-
- public $lat;
-
- public $country;
-
- public function __construct($id, $name, $lon, $lat, $country)
- {
- $this->id = (int)$id;
- $this->name = (string)$name;
- $this->lon = (float)$lon;
- $this->lat = (float)$lat;
- $this->country = (string)$country;
- }
-}
-
-class _Weather
-{
- public $id;
-
- public $description;
-
- public $icon;
-
- private $iconUrl = "http://openweathermap.org/img/w/%s.png";
-
- public function __construct($id, $description, $icon)
- {
- $this->id = (int)$id;
- $this->description = (string)$description;
- $this->icon = (string)$icon;
- }
-
- public function __toString()
- {
- return $this->description;
- }
-
- public function getIconUrl()
- {
- return str_replace("%s", $this->icon, $this->iconUrl);
- }
-}
-
-class OpenWeatherMap_Exception extends Exception
-{
-
-}
diff --git a/OpenWeatherMap.php b/cmfcmf/OpenWeatherMap.php
similarity index 64%
rename from OpenWeatherMap.php
rename to cmfcmf/OpenWeatherMap.php
index cdb9998..7e26141 100644
--- a/OpenWeatherMap.php
+++ b/cmfcmf/OpenWeatherMap.php
@@ -14,7 +14,14 @@
* @see http://openweathermap.org/appid
*/
-require_once('Util.php');
+namespace cmfcmf {
+
+use cmfcmf\OpenWeatherMap\Weather;
+
+# Install PSR-0-compatible class autoloader
+spl_autoload_register(function($class){
+ require preg_replace('{\\\\|_(?!.*\\\\)}', DIRECTORY_SEPARATOR, ltrim($class, '\\')).'.php';
+});
/**
* Main static class for the OpenWeatherMap-PHP-API.
@@ -22,10 +29,39 @@
class OpenWeatherMap
{
/**
- * @const $url The basic api url to fetch data from.
+ * @var $url The basic api url to fetch data from.
*/
- const url = "http://api.openweathermap.org/data/2.5/weather?";
+ private $url = "http://api.openweathermap.org/data/2.5/weather?";
+
+ private $cacheClass = false;
+
+ private $seconds;
+ /**
+ * Constructs the OpenWeatherMap object.
+ *
+ * @param bool|string $cache If set to false, caching is disabled. If this is a valid class
+ * extending cmfcmf\OpenWeatherMap\Util\Cache, caching will be enabled. Default false.
+ * @param int $seconds How long weather data shall be cached. Default 10 minutes.
+ *
+ * @throws Exception If $cache is neither false nor a valid callable extending cmfcmf\OpenWeatherMap\Util\Cache.
+ */
+ public function __construct($cacheClass = false, $seconds = 600)
+ {
+ if (!class_exists($cacheClass) && $cacheClass !== false) {
+ #throw new \Exception("Class $cacheClass does not exist.");
+ }
+ if (!is_numeric($seconds)) {
+ throw new \Exception("\$seconds must be numeric.");
+ }
+ if ($seconds == 0) {
+ $cacheClass = false;
+ }
+
+ $this->cacheClass = $cacheClass;
+ $this->seconds = $seconds;
+ }
+
/**
* Directly returns the xml/json/html string returned by OpenWeatherMap.
*
@@ -63,30 +99,45 @@ class OpenWeatherMap
* - Chinese Simplified - zh_cn
* - Turkish - tr
*/
- static public function getRawData($query, $units = 'imperial', $lang = 'en', $appid = '', $mode = 'xml')
+ public function getRawData($query, $units = 'imperial', $lang = 'en', $appid = '', $mode = 'xml')
{
switch($query) {
case (is_array($query)):
if (!is_numeric($query['lat']) || !is_numeric($query['lon'])) {
return false;
}
- $query = "lat={$query['lat']}&lon={$query['lon']}";
+ $queryUrl = "lat={$query['lat']}&lon={$query['lon']}";
break;
case (is_numeric($query)):
- $query = "id=$query";
+ $queryUrl = "id=$query";
break;
case (is_string($query)):
- $query = "q=" . urlencode($query);
+ $queryUrl = "q=" . urlencode($query);
break;
default:
return false;
}
- $url = self::url . "$query&units=$units&lang=$lang&mode=$mode";
+
+ $url = $this->url . "$queryUrl&units=$units&lang=$lang&mode=$mode";
if (!empty($appid)) {
$url .= "&APPID=$appid";
}
+
+ $result = "";
- return file_get_contents($url);
+ if ($this->cacheClass !== false) {
+ $cache = new $this->cacheClass;
+ $cache->setSeconds($this->seconds);
+ if ($cache->isCached($query, $units, $lang, $mode)) {
+ return $cache->getCached();
+ }
+ $result = $this->fetch($url);
+ $cache->setCached($result, $query, $units, $lang, $mode);
+ } else {
+ $result = $this->fetch($url);
+ }
+
+ return $result;
}
/**
@@ -126,8 +177,15 @@ static public function getRawData($query, $units = 'imperial', $lang = 'en', $ap
* - Chinese Simplified - zh_cn
* - Turkish - tr
*/
- static public function getWeather($query, $units = 'imperial', $lang = 'en', $appid = '')
+ public function getWeather($query, $units = 'imperial', $lang = 'en', $appid = '')
{
- return new Weather($query, $units, $lang, $appid);
+ return new Weather($query, $units, $lang, $appid, $this->cacheClass, $this->seconds);
}
+
+ private function fetch($url)
+ {
+ return file_get_contents($url);
+ }
+}
+
}
diff --git a/cmfcmf/OpenWeatherMap/AbstractCache.php b/cmfcmf/OpenWeatherMap/AbstractCache.php
new file mode 100644
index 0000000..7d97d7c
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/AbstractCache.php
@@ -0,0 +1,74 @@
+seconds = $seconds;
+ }
+}
diff --git a/cmfcmf/OpenWeatherMap/Exception.php b/cmfcmf/OpenWeatherMap/Exception.php
new file mode 100644
index 0000000..1031952
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/Exception.php
@@ -0,0 +1,26 @@
+id = (int)$id;
+ $this->name = (string)$name;
+ $this->lon = (float)$lon;
+ $this->lat = (float)$lat;
+ $this->country = (string)$country;
+ }
+}
diff --git a/cmfcmf/OpenWeatherMap/Util/Sun.php b/cmfcmf/OpenWeatherMap/Util/Sun.php
new file mode 100644
index 0000000..3b112e3
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/Util/Sun.php
@@ -0,0 +1,30 @@
+rise = $rise;
+ $this->set = $set;
+ }
+}
diff --git a/cmfcmf/OpenWeatherMap/Util/Temperature.php b/cmfcmf/OpenWeatherMap/Util/Temperature.php
new file mode 100644
index 0000000..e7c6d89
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/Util/Temperature.php
@@ -0,0 +1,58 @@
+now = $now;
+ $this->min = $min;
+ $this->max = $max;
+ }
+
+ public function __toString()
+ {
+ return $this->now->__toString();
+ }
+
+ public function getUnit()
+ {
+ return $this->now->getUnit();
+ }
+
+ public function getValue()
+ {
+ return $this->now->getValue();
+ }
+
+ public function getDescription()
+ {
+ return $this->now->getDescription();
+ }
+
+ public function getFormatted()
+ {
+ return $this->now->getFormatted();
+ }
+}
diff --git a/cmfcmf/OpenWeatherMap/Util/Unit.php b/cmfcmf/OpenWeatherMap/Util/Unit.php
new file mode 100644
index 0000000..c0bb734
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/Util/Unit.php
@@ -0,0 +1,73 @@
+value = (float)$value;
+ $this->unit = (string)$unit;
+ $this->description = (string)$description;
+ }
+
+ public function __toString()
+ {
+ return $this->getFormatted();
+ }
+
+ public function getUnit()
+ {
+ // Units are inconsistent. Only celsius and fahrenheit are not abbreviated. This check fixes that.
+ if ($this->unit == 'celsius') {
+ return '°C';
+ } else if ($this->unit == 'fahrenheit') {
+ return 'F';
+ } else {
+ return $this->unit;
+ }
+ }
+
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ public function getFormatted()
+ {
+ if ($this->getUnit() != "") {
+ return "{$this->getValue()} {$this->getUnit()}";
+ } else {
+ return "{$this->getValue()}";
+ }
+ }
+}
+
diff --git a/cmfcmf/OpenWeatherMap/Util/Weather.php b/cmfcmf/OpenWeatherMap/Util/Weather.php
new file mode 100644
index 0000000..42abda3
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/Util/Weather.php
@@ -0,0 +1,45 @@
+id = (int)$id;
+ $this->description = (string)$description;
+ $this->icon = (string)$icon;
+ }
+
+ public function __toString()
+ {
+ return $this->description;
+ }
+
+ public function getIconUrl()
+ {
+ return str_replace("%s", $this->icon, $this->iconUrl);
+ }
+}
diff --git a/cmfcmf/OpenWeatherMap/Util/Wind.php b/cmfcmf/OpenWeatherMap/Util/Wind.php
new file mode 100644
index 0000000..84f4de5
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/Util/Wind.php
@@ -0,0 +1,30 @@
+speed = $speed;
+ $this->direction = $direction;
+ }
+}
diff --git a/cmfcmf/OpenWeatherMap/Weather.php b/cmfcmf/OpenWeatherMap/Weather.php
new file mode 100644
index 0000000..a8df6d8
--- /dev/null
+++ b/cmfcmf/OpenWeatherMap/Weather.php
@@ -0,0 +1,109 @@
+OpenWeatherMap.org";
+
+ public function __construct($query, $units = 'imperial', $lang = 'en', $appid = '', $cacheClass = false, $seconds = 600)
+ {
+ // Disable default error handling of SimpleXML (Do not throw E_WARNINGs).
+ libxml_use_internal_errors(true);
+ libxml_clear_errors();
+
+ $owm = new OpenWeatherMap($cacheClass, $seconds);
+
+ $answer = $owm->getRawData($query, $units, $lang, $appid, 'xml');
+ if ($answer === false) {
+ // $query has the wrong format, throw error.
+ throw new \Exception('Error: $query has the wrong format. See the documentation of OpenWeatherMap::getRawData() to read about valid formats.');
+ }
+
+ try {
+ $xml = new \SimpleXMLElement($answer);
+ } catch(\Exception $e) {
+ // Invalid xml format. This happens in case OpenWeatherMap returns an error.
+ // OpenWeatherMap always uses json for errors, even if one specifies xml as format.
+ $error = json_decode($answer, true);
+ if (isset($error['message'])) {
+ throw new OWMException($error['message'], $error['cod']);
+ } else {
+ throw new OWMException('Unknown fatal error: OpenWeatherMap returned the following json object: ' . print_r($error));
+ }
+ }
+
+ $this->city = new City($xml->city['id'], $xml->city['name'], $xml->city->coord['lon'], $xml->city->coord['lat'], $xml->city->country);
+ $this->temperature = new Temperature(new Unit($xml->temperature['value'], $xml->temperature['unit']), new Unit($xml->temperature['min'], $xml->temperature['unit']), new Unit($xml->temperature['max'], $xml->temperature['unit']));
+ $this->humidity = new Unit($xml->humidity['value'], $xml->humidity['unit']);
+ $this->pressure = new Unit($xml->pressure['value'], $xml->pressure['unit']);
+
+
+ // This is kind of a hack, because the units are missing in the xml document.
+ if ($units == 'metric') {
+ $windSpeedUnit = 'm/s';
+ } else {
+ $windSpeedUnit = 'mph';
+ }
+ $this->wind = new Wind(new Unit($xml->wind->speed['value'], $windSpeedUnit, $xml->wind->speed['name']), new Unit($xml->wind->direction['value'], $xml->wind->direction['code'], $xml->wind->direction['name']));
+
+
+ $this->clouds = new Unit($xml->clouds['value'], null, $xml->clouds['name']);
+ $this->precipitation = new Unit($xml->precipitation['value'], $xml->precipitation['unit'], $xml->precipitation['mode']);
+ $this->sun = new Sun(new \DateTime($xml->city->sun['rise']), new \DateTime($xml->city->sun['set']));
+ $this->weather = new WeatherObj($xml->weather['number'], $xml->weather['value'], $xml->weather['icon']);
+ $this->lastUpdate = new \DateTime($xml->lastupdate['value']);
+ }
+}
diff --git a/composer.json b/composer.json
index c3bbd0b..fbd1765 100644
--- a/composer.json
+++ b/composer.json
@@ -18,5 +18,10 @@
},
"require": {
"php": ">=5.3.0"
+ },
+ "autoload": {
+ "psr-0": {
+ "cmfcmf\\": ""
+ }
}
}
diff --git a/examplecache.php b/examplecache.php
new file mode 100644
index 0000000..558a56a
--- /dev/null
+++ b/examplecache.php
@@ -0,0 +1,24 @@
+";
+ return false;
+ }
+
+ public function getCached($query, $units, $lang, $mode)
+ {
+ echo "Get cache for $query $units $lang $mode …
";
+ return false;
+ }
+
+ public function setCached($content, $query, $units, $lang, $mode)
+ {
+ echo "Set cache for $query $units $lang $mode … ({$this->seconds} seconds)
";
+ return false;
+ }
+}