kabudu / forecast-tools
这是Forecast.io API的包装器,支持许多同时API调用,显著减少了需要批量查询天气条件的应用程序的等待时间。
Requires
- php: >=5.3.2
Requires (Dev)
- phpunit/phpunit: 4.8.*@dev
- predis/predis: v1.0.1
Suggests
- predis/predis: Flexible and feature-complete PHP client library for Redis to use the Redis cache handler
- redis: >= 2.8 to use the redis cache handler
This package is not auto-updated.
Last update: 2024-09-14 17:16:21 UTC
README
这是Forecast.io API的包装器,支持许多同时API调用,显著减少了需要批量查询天气条件的应用程序的等待时间。
注意:如果您永远不会同时发送超过一个请求或者缓存结果,您可能想尝试Guilherm Uhelski的更简单的forecast-php项目。
关于Forecast API
网络上最容易用、最先进的天气API
为Forecast.io和Dark Sky for iOS提供动力的相同API可以向您的企业、应用程序或疯狂想法提供准确的中长期天气预报。
多cURL的力量
包含的example.php
被用来演示各种组合的总请求数和并发线程数。此表显示了秒数,每个值是三次试验的平均值。
Total Requests
Threads 10 100 250 500
1 3.25 31.39 75.19 155.73
5 1.00 9.49 23.02 43.05
10 0.65 5.36 14.61 27.04
25 0.49 5.02 9.90 18.20
50 0.59 2.93 6.97 14.74
100 0.50 2.35 7.23 12.14
这显示了使用ForecastTools与100个线程相比,速度提高了十倍以上。 注意:由于服务器负载的考虑,Dark Sky公司建议使用10个线程,因此这是当前的默认值。请谨慎更改此值。
要求
PHP配置
要处理多个并发API调用,此包装器需要cURL并依赖于libcurl-multi。如果您已安装cURL,您可能已经有了所需的所有内容。
对于单个API调用,此包装器如果可用则使用cURL,否则回退到PHP函数file_get_contents,该函数本身需要在您的php.ini文件中设置allow_url_fopen On
,这启用了URL感知fopen包装器。
API密钥
您需要一个API密钥,这需要在注册Forecast for Developers后获得。
安装
FTP程序
- 下载ForecastTools
- 解压ZIP文件
- 将
ForecastTools-master
重命名为ForecastTools
- 使用FTP程序将
ForecastTools
上传到您的Web服务器
控制台(高级)
如果您的主目录是/var/www/html
,以下是您可以将文件复制到服务器的示例
$ cd /var/www/html
$ wget -O ForecastTools.zip https://github.com/CNG/ForecastTools/archive/master.zip
$ unzip ForecastTools.zip
$ rm -f ForecastTools.zip
$ mv ForecastTools-master ForecastTools
Composer(高级)
-
如果您尚未安装Composer,请在此了解更多关于Composer的详细信息
-
将以下内容添加到您的composer.json文件中
"require": { "kabudu/forecast-tools": "1.2" }
-
运行composer install
结构
本项目是一系列类,实现了API响应的各个分支。位于 lib
目录下的PHP文件都有详细的文档,你可以依赖它们,而无需参考官方的 API文档。
以下是基本结构
Forecast
对象向API发起请求,可以返回包含JSON响应的 ForecastResponse
对象。 ForecastResponse
对象可以返回用于访问天气条件的 ForecastDataPoint
对象,以及用于访问元数据的 ForecastAlert
和 ForecastFlags
对象。
使用方法
当前条件,单次请求
以下是如何根据一些GPS坐标获取当前温度的示例
<?php
require_once 'lib/Forecast.php';
// The Castro
$latitude = 37.770452;
$longitude = -122.424923;
// Make request to the API for the current forecast
$forecast = new Forecast('YOUR_API_KEY_HERE');
$response = $forecast->getData($latitude, $longitude);
$currently = $response->getCurrently();
$time = date("H:i:s", $currently->getTime());
$temp = number_format($currently->getTemperature(), 1);
echo "Temperature in the Castro at $time: $temp℉<br />\n";
?>
你可以忽略 ForecastDataPoint
、ForecastAlerts
和 ForecastFlags
类的getter方法,直接处理API响应。以下是一个例子
<?php
$data = $response->getRawData();
var_dump($data);
?>
历史条件,多次请求
以下是如何获取从现在到75年前每个月份的当前温度的示例
<?php
require_once 'lib/Forecast.php';
$threads = 10;
$forecast = new Forecast('YOUR_API_KEY_HERE', $threads);
// The Castro
$latitude = 37.770452;
$longitude = -122.424923;
// Build requests for current time each month in last 75 years
$requests = array();
for ($i = 0; $i < 75*12; $i++) {
$requests[] = array(
'latitude' => $latitude,
'longitude' => $longitude,
'time' => strtotime("-$i months"),
);
}
// Make requests to the API
$responses = $forecast->getData($requests);
foreach ($responses as $response) {
if ($currently = $response->getCurrently()) {
$time = date("Y-m-d H:i:s", $currently->getTime());
$temp = $currently->getTemperature()
? number_format($currently->getTemperature(), 2) . '℉'
: "unknown";
echo "$time: $temp<br />\n";
}
}
?>
文档
lib
目录下的PHP文件都有详细的文档,你可以依赖它们,而无需参考官方的 API文档。
还有由 phpDocumentor 生成的文档,可以在我的网站上找到 这里,或者你可以使用以下命令从源代码中生成自己的文档:
phpdoc -d /path/to/ForecastTools/lib -t docs --template abstract
一般来说,如果数据不可用或发生错误,任何东西都可能返回false,因此要编写防御性代码。
Forecast
实例化
$forecast = new Forecast('YOUR_API_KEY_HERE');
单次请求
$response = $forecast->getData(float, float[, int]);
多次同时请求
$requests = array(
array('latitude' => float, 'longitude' => float, 'time' => int),
array('latitude' => float, 'longitude' => float, 'time' => int),
array('latitude' => float, 'longitude' => float, 'time' => int),
);
$responses = $forecast->getData($requests);
使用redis缓存处理程序
$predisClient = new \Predis\Client();
$cacheHandler = new \ForecastTools\Cache\RedisCacheHandler($predisClient);
$requests = array(
array('latitude' => float, 'longitude' => float, 'time' => int, 'cache_enabled' => true, 'cache_handler' => $cacheHandler, 'cache_timeout' => int),
);
$responses = $forecast->getData($requests);
ForecastResponse
ForecastResponse对象用于访问针对给定请求从Forecast.io返回的各种数据块。通常,为了确定特定时间点的天气,应该检查定义的最高精度数据块(分别为分钟、小时和日),并从其中获取任何可用的数据,对于所需时间点缺失的任何属性,则回退到下一个最高精度数据块。
由 Forecast->getData()
返回
单次请求
$response->getRawData();
多次请求
foreach ($responses as $response) {
$response->getRawData();
}
其他方法
请求的时间和位置属性
getAlerts()
返回一个ForecastAlert
对象数组getFlags()
返回ForecastFlags
对象getCurrently()
返回一个ForecastDataPoint
对象数组getLatitude()
getLongitude()
getOffset()
getTimezone()
在请求的位置和时间周围的预测或历史条件
getMinutely()
返回一个ForecastDataPoint
对象数组getHourly()
返回一个ForecastDataPoint
对象数组getDaily()
返回一个ForecastDataPoint
对象数组
前三个方法可以接受一个可选的基于零的整数参数,以返回集合中的特定 ForecastDataPoint
对象。可以与 getCount(string)
一起使用。
getCount($type)
返回在指定块中存在的ForecastDataPoint
对象的数量。$type可以是'minutely'、'hourly'或'daily'。
ForecastDataPoint
ForecastDataPoint对象表示在特定时间点发生的各种天气现象,并且有许多不同的方法。所有这些方法(除时间外)都是可选的,并且只有在该位置和时间有那种类型的信息时才会设置。请注意,分钟数据点始终对齐到最近的分钟边界,小时数据点对齐到整点,日数据点对齐到当天的午夜。以下列出的每日数据块中的数据点具有特殊性:它们不是表示给定时间点的天气现象,而是表示整个一天内将要发生的天气现象的总和。对于降水量字段,这个总和是最大值;对于其他字段,是平均值。以下方法由于缺乏文档而没有实现为获取函数:所有数据导向的方法都可能有一个相关的错误值定义,表示我们系统对其预测的信心。这些属性表示其相关属性的值的标准偏差;因此,小的误差值表示强烈的信心,而大的误差值表示弱的信心。在信心不精确已知的地方(尽管通常被认为是足够的)省略了这些属性。
getTime()
返回此数据点发生的UNIX时间(即,1970年1月1日午夜GMT以来的秒数)。getSummary()
返回此数据点的人可读文本摘要。getIcon()
返回此数据点的机器可读文本摘要,适合用于选择显示的图标。如果定义了此属性,它将具有以下值之一:clear-day(晴朗白天)、clear-night(晴朗夜晚)、rain(雨)、snow(雪)、sleet(雨夹雪)、wind(风)、fog(雾)、cloudy(多云)、partly-cloudy-day(部分多云白天)或partly-cloudy-night(部分多云夜晚)。(开发者应确保定义了一个合理的默认值,因为未来可能会定义额外的值,如hail(冰雹)、thunderstorm(雷暴)或tornado(龙卷风)。)getSunriseTime()
返回(仅在每日数据点上定义)给定日期日出和日落时的UNIX时间(即,1970年1月1日午夜GMT以来的秒数)。如果给定日期不会发生日出或日落,则相应的字段将未定义。这可能在夏季和冬季在非常高的或非常低的纬度地区发生。getSunsetTime()
返回(仅在每日数据点上定义)给定日期日出和日落时的UNIX时间(即,1970年1月1日午夜GMT以来的秒数)。如果给定日期不会发生日出或日落,则相应的字段将未定义。这可能在夏季和冬季在非常高的或非常低的纬度地区发生。getPrecipIntensity()
返回一个数值,表示基于概率(即,假设有任何降水发生)在给定时间发生的降水平均预期强度(以每小时液态水的英寸为单位)。一个非常粗略的指南是,0英寸/小时对应无降水,0.002英寸/小时对应非常轻微的降水,0.017英寸/小时对应轻微降水,0.1英寸/小时对应中等降水,0.4英寸/小时对应大雨。getPrecipIntensityMax()
返回(仅在每日数据点上定义)表示给定一天预期降水最大强度(及其发生的UNIX时间)的数值,以每小时液态水的英寸为单位。getPrecipIntensityMaxTime()
返回(仅在每日数据点上定义)表示给定一天预期降水最大强度(及其发生的UNIX时间)的数值,以每小时液态水的英寸为单位。getPrecipProbability()
返回一个在0和1之间(含0和1)的数值,表示给定时间发生降水的概率。getPrecipType()
返回一个字符串,表示给定时间正在发生的降水类型。如果定义了此方法,它将具有以下值之一:雨、雪、雨夹雪(适用于冰雨、冰粒和“冬季混合”),或冰雹。(如果 getPrecipIntensity() 返回 0,则此方法应返回 false。)getPrecipAccumulation()
返回(仅在每日数据点上定义)预计在给定一天发生的降雪累积量。(如果预计没有累积,则此方法应返回 false。)getTemperature()
返回(不在每日数据点上定义)表示给定时间的温度的数值(华氏度)。getTemperatureMin()
返回(仅在每日数据点上定义)表示给定一天最低温度的数值(华氏度)。getTemperatureMinTime()
返回(仅在每日数据点上定义)表示给定一天最低温度(及其发生的 UNIX 时间)的数值(华氏度)。getTemperatureMax()
返回(仅在每日数据点上定义)表示给定一天最高温度(及其发生的 UNIX 时间)的数值(华氏度)。getTemperatureMaxTime()
返回(仅在每日数据点上定义)表示给定一天最高温度(及其发生的 UNIX 时间)的数值(华氏度)。getApparentTemperature()
返回(不在每日数据点上定义)表示给定时间的实际(或“感觉”)温度的数值(华氏度)。getApparentTemperatureMin()
返回(仅在每日数据点上定义)表示给定一天最低实际温度的数值(华氏度)。getApparentTemperatureMinTime()
返回(仅在每日数据点上定义)表示给定一天最低实际温度(及其发生的 UNIX 时间)的数值(华氏度)。getApparentTemperatureMax()
返回(仅在每日数据点上定义)表示给定一天最高实际温度(及其发生的 UNIX 时间)的数值(华氏度)。getApparentTemperatureMaxTime()
返回(仅在每日数据点上定义)表示给定一天最高实际温度(及其发生的 UNIX 时间)的数值(华氏度)。getDewPoint()
返回表示给定时间的露点的数值(华氏度)。getWindSpeed()
返回表示风速的数值(每小时英里)。getWindBearing()
返回表示风来自哪个方向的数值(以度为单位),其中真北为 0°,顺时针方向递增。(如果 getWindSpeed 为零,则此值将未定义。)getCloudCover()
返回介于 0 和 1(含)之间的数值,表示被云层遮挡的天空百分比。0 表示晴朗天空,0.4 表示散布的云,0.75 表示破碎云层覆盖,1 表示完全阴天。getHumidity()
返回介于 0 和 1(含)之间的数值,表示相对湿度。getPressure()
返回表示海平面空气压力的数值(毫巴)。getVisibility()
返回表示平均能见度的数值(英里),上限为 10 英里。getOzone()
返回表示给定时间大气总臭氧柱密度的数值(杜博森单位)。
预报警报
警报对象表示政府机构针对请求的位置发布的严重天气警告(有关我们目前支持哪些机构的列表,请参阅数据源 https://developer.forecast.io/docs/v2)
getDescription()
返回来自适当天气服务的警报的详细文本描述。getExpires()
返回警报失效的UNIX时间(即自1970年1月1日午夜GMT以来经过的秒数)。getTitle()
返回警报的简短文本摘要。getURI()
返回包含警报详细信息的HTTP(S) URI。
ForecastFlags
标志对象包含与请求相关的各种元数据信息。
getDarkskyUnavailable()
此属性的存在表示Dark Sky数据源支持给定位置,但临时错误(例如雷达站因维护而关闭)使得数据不可用。getDarkskyStations()
返回在处理此请求中使用的每个雷达站的ID数组。getDatapointStations()
返回在处理此请求中使用的每个DataPoint站的ID数组。getISDStations()
返回在处理此请求中使用的每个ISD站的ID数组。getLAMPStations()
返回在处理此请求中使用的每个LAMP站的ID数组。getMETARStations()
返回在处理此请求中使用的每个METAR站的ID数组。getMetnoLicense()
此属性的存在表示为了处理此请求而使用了api.met.no的数据(根据他们的许可协议)。getSources()
返回在处理此请求中使用的每个数据源的ID数组。getUnits()
此属性的存在表示在此请求中使用的数据的单位。
注意事项
在反复测试许多(1000+)请求的过程中,我遇到了一些不一致的错误,例如cURL返回错误
Unknown SSL protocol error in connection to api.forecast.io:443
当在短时间内进行较少的请求时,这些错误不会发生,因此我将它们归因于服务限制。如果您打算使用ForecastTools进行大量请求,则需要进一步探索。
更新日志
- 版本1.0:2013年10月7日
- 首次发布
- 版本1.1:2015年3月2日,由Shannon Little发布
- 增加了缓存数据的功能
- 增加了获取最近风暴数据的方法
- 版本1.2:2015年6月21日,由Kamba Abudu发布
- 更新库以使用命名空间并遵循PSR1/PSR2/PSR4
- 实现了一个用于缓存处理器的接口和Redis缓存处理器
- 增加了在多cURL上下文中缓存数据的能力
即将推出
我为自己的应用程序编写了一个额外的层,用于在Weatherbit中缓存请求到MySQL数据库,以防止对API进行重复查询。这对于可能会重复请求相同信息的应用程序特别有用,例如Weatherbit用户每天检查他的30天图表。我计划对其进行一些抽象,并将其最终包含在这个包装器中。如果您想早点看到我所做的事情,请随时给我发消息。