本文目录导读:

我来详细说明PHP项目对接天气查询接口的完整流程,以国内常用的和风天气和OpenWeatherMap为例。
准备工作
选择天气API服务商
- 和风天气 (国内首选):https://dev.heweather.com
- OpenWeatherMap (国际):https://openweathermap.org
- 彩云天气:https://docs.caiyunapp.com
获取API密钥
以和风天气为例:
- 注册账号
- 创建应用获取
API Key - 选择免费版或付费版
PHP对接实现
基础封装类
<?php
class WeatherAPI {
private $apiKey;
private $baseUrl;
public function __construct($apiKey, $service = 'heweather') {
$this->apiKey = $apiKey;
// 根据服务商设置base URL
switch ($service) {
case 'heweather':
$this->baseUrl = 'https://devapi.qweather.com/v7';
break;
case 'openweather':
$this->baseUrl = 'https://api.openweathermap.org/data/2.5';
break;
}
}
/**
* 发送HTTP请求
*/
private function sendRequest($url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if (curl_errno($ch)) {
throw new Exception('CURL Error: ' . curl_error($ch));
}
curl_close($ch);
if ($httpCode !== 200) {
throw new Exception("HTTP Error: $httpCode");
}
return json_decode($response, true);
}
/**
* 获取实时天气 - 和风天气
*/
public function getCurrentWeather($location) {
$url = $this->baseUrl . "/weather/now?location=$location&key={$this->apiKey}";
return $this->sendRequest($url);
}
/**
* 获取未来3天天气预报 - 和风天气
*/
public function getForecast($location, $days = 3) {
$url = $this->baseUrl . "/weather/3d?location=$location&key={$this->apiKey}";
return $this->sendRequest($url);
}
/**
* 获取实时天气 - OpenWeatherMap
*/
public function getCurrentWeatherOWM($location) {
$url = $this->baseUrl . "/weather?q=$location&appid={$this->apiKey}&units=metric&lang=zh_cn";
return $this->sendRequest($url);
}
}
使用示例
<?php
// 1. 基础使用 - 获取实时天气
try {
$weather = new WeatherAPI('YOUR_API_KEY_HERE', 'heweather');
$result = $weather->getCurrentWeather('101010100'); // 北京城市ID
if ($result['code'] === '200') {
$now = $result['now'];
echo "当前温度:{$now['temp']}°C\n";
echo "天气状况:{$now['text']}\n";
echo "风速:{$now['windSpeed']} km/h\n";
echo "湿度:{$now['humidity']}%\n";
}
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
// 2. 通过城市名称查询
function getWeatherByName($cityName) {
// 先获取城市ID (和风天气需要)
$geoUrl = "https://geoapi.qweather.com/v2/city/lookup";
$geoUrl .= "?location=$cityName&key=YOUR_API_KEY";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $geoUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$geoResponse = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!empty($geoResponse['location'])) {
$cityId = $geoResponse['location'][0]['id'];
// 使用城市ID查询天气
$weatherAPI = new WeatherAPI('YOUR_API_KEY');
return $weatherAPI->getCurrentWeather($cityId);
}
return null;
}
// 3. 通过IP定位获取天气
function getWeatherByIP() {
$ip = $_SERVER['REMOTE_ADDR'] ?? '8.8.8.8'; // 生产环境使用真实IP
// 使用和风天气的IP定位
$locationUrl = "https://geoapi.qweather.com/v2/ip?key=YOUR_API_KEY&ip=$ip";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $locationUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$location = json_decode(curl_exec($ch), true);
curl_close($ch);
if (!empty($location['location'])) {
$cityId = $location['location'][0]['id'];
$weatherAPI = new WeatherAPI('YOUR_API_KEY');
return $weatherAPI->getCurrentWeather($cityId);
}
return null;
}
进阶功能封装
带缓存的天气预报类
<?php
class WeatherService {
private $api;
private $cacheDir;
private $cacheTime = 1800; // 30分钟缓存
public function __construct($apiKey) {
$this->api = new WeatherAPI($apiKey);
$this->cacheDir = __DIR__ . '/cache/weather/';
if (!is_dir($this->cacheDir)) {
mkdir($this->cacheDir, 0755, true);
}
}
/**
* 获取天气(带缓存)
*/
public function getWeatherWithCache($location) {
$cacheFile = $this->cacheDir . md5($location) . '.json';
// 检查缓存
if (file_exists($cacheFile) && (time() - filemtime($cacheFile)) < $this->cacheTime) {
return json_decode(file_get_contents($cacheFile), true);
}
// 从API获取数据
$data = $this->api->getCurrentWeather($location);
// 写入缓存
if (!empty($data)) {
file_put_contents($cacheFile, json_encode($data));
}
return $data;
}
/**
* 获取格式化天气报告
*/
public function getWeatherReport($location) {
$data = $this->getWeatherWithCache($location);
if (isset($data['now'])) {
$now = $data['now'];
return [
'temperature' => $now['temp'] . '°C',
'feels_like' => $now['feelsLike'] . '°C',
'condition' => $now['text'],
'wind' => $now['windDir'] . ' ' . $now['windScale'] . '级',
'humidity' => $now['humidity'] . '%',
'update_time' => $data['updateTime']
];
}
return null;
}
}
// 使用示例
$weatherService = new WeatherService('YOUR_API_KEY');
$report = $weatherService->getWeatherReport('101010100');
echo "当前温度:{$report['temperature']}\n";
echo "天气状况:{$report['condition']}\n";
前端展示示例(HTML+JS)
<!-- weather_display.php -->
<!DOCTYPE html>
<html>
<head>天气预报</title>
<style>
.weather-card {
border: 1px solid #ddd;
border-radius: 8px;
padding: 20px;
margin: 20px;
max-width: 300px;
}
.temperature {
font-size: 48px;
font-weight: bold;
color: #333;
}
.condition {
font-size: 24px;
color: #666;
}
</style>
</head>
<body>
<div id="weather" class="weather-card">
<h2>当前天气</h2>
<div class="temperature" id="temp">--°C</div>
<div class="condition" id="condition">加载中...</div>
</div>
<script>
function updateWeather() {
fetch('api/get_weather.php?city=北京')
.then(response => response.json())
.then(data => {
document.getElementById('temp').textContent =
data.temperature + '°C';
document.getElementById('condition').textContent =
data.condition;
})
.catch(error => {
console.error('获取天气失败:', error);
});
}
// 每30分钟更新一次
updateWeather();
setInterval(updateWeather, 1800000);
</script>
</body>
</html>
PHP API端点
<?php
// api/get_weather.php
header('Content-Type: application/json');
header('Access-Control-Allow-Origin: *');
require_once '../WeatherService.php';
try {
$city = $_GET['city'] ?? '北京';
$weatherService = new WeatherService('YOUR_API_KEY');
$report = $weatherService->getWeatherReport($city);
if ($report) {
echo json_encode([
'success' => true,
'temperature' => $report['temperature'],
'condition' => $report['condition'],
'humidity' => $report['humidity'],
'wind' => $report['wind']
]);
} else {
echo json_encode(['success' => false, 'message' => '天气数据获取失败']);
}
} catch (Exception $e) {
echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
错误处理和注意事项
错误处理
try {
$weather = new WeatherAPI('YOUR_API_KEY');
$result = $weather->getCurrentWeather('invalid_location');
if ($result['code'] !== '200') {
// 错误处理
switch ($result['code']) {
case '401':
throw new Exception('API密钥无效');
case '403':
throw new Exception('请求被拒绝');
case '404':
throw new Exception('城市不存在');
default:
throw new Exception('未知错误');
}
}
} catch (Exception $e) {
error_log("Weather API Error: " . $e->getMessage());
echo json_encode(['error' => $e->getMessage()]);
}
性能优化建议
// 1. 使用连接池(如Redis缓存)
class WeatherCache {
private $redis;
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function getCachedWeather($location) {
$key = "weather:$location";
$cached = $this->redis->get($key);
if ($cached) {
return json_decode($cached, true);
}
// 从API获取并缓存
$weather = new WeatherAPI('YOUR_API_KEY');
$data = $weather->getCurrentWeather($location);
// 缓存30分钟
$this->redis->setex($key, 1800, json_encode($data));
return $data;
}
}
// 2. 批量查询优化
function batchGetWeather(array $locations) {
$results = [];
foreach ($locations as $location) {
// 使用多线程或curl_multi并行请求
$results[$location] = getWeatherFromAPI($location);
}
return $results;
}
安全注意事项
// 1. API密钥安全存储
// 不要在代码中硬编码API密钥,使用环境变量
$apiKey = getenv('WEATHER_API_KEY');
// 2. 请求频率限制
class RateLimiter {
private $requests = [];
private $limit = 100; // 每分钟100次
public function checkLimit() {
$now = time();
$this->requests = array_filter($this->requests, function($time) use ($now) {
return $time > ($now - 60);
});
if (count($this->requests) >= $this->limit) {
throw new Exception('请求频率超限');
}
$this->requests[] = $now;
}
}
// 3. 输入验证
function validateLocation($location) {
// 只允许字母、数字和中文
if (!preg_match('/^[a-zA-Z0-9\x{4e00}-\x{9fa5}]+$/u', $location)) {
throw new Exception('无效的位置参数');
}
return true;
}
完整项目结构
weather_project/
├── api/
│ └── get_weather.php # API端点
├── classes/
│ ├── WeatherAPI.php # API封装类
│ ├── WeatherService.php # 业务逻辑封装
│ └── WeatherCache.php # 缓存类
├── config/
│ └── config.php # 配置文件
├── templates/
│ └── weather_display.php # 前端模板
├── cache/ # 缓存目录
├── vendor/ # Composer依赖
├── .env # 环境变量
└── index.php # 入口文件
配置文件示例
<?php
// config/config.php
return [
'weather_api' => [
'service' => 'heweather', // heweather, openweather
'api_key' => getenv('WEATHER_API_KEY'),
'cache_time' => 1800, // 缓存时间(秒)
'timeout' => 10, // 请求超时(秒)
'retry_times' => 3, // 重试次数
]
];
对接天气API的关键要点:
- 选择合适的API服务商:国内推荐和风天气,国际推荐OpenWeatherMap
- 实现缓存机制:减少API调用次数,提高响应速度
- 错误处理:完善异常捕获和错误提示
- 性能优化:使用缓存、连接池等技术
- 安全性:保护API密钥,验证用户输入
这样,你就可以在自己的PHP项目中轻松集成天气查询功能了,如果需要其他天气API的对接方式,可以进一步告诉我。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播