利用简码实现一个 WordPress 天气小工具
转载前请务必事先联系并取得本人授权,同时需保留原文链接及明确的转载声明。未经许可,不得擅自用于商业用途。
Copyright © 2024-2025 SALTWOOD. All rights reserved.
此工具是动态的,而缓存插件可能会把结果缓存,因此使用此工具请不要启用缓存插件,否则可能泄露访客来源信息。

简单来说,就是实现像站点右侧的这个小东西一样的一个天气小工具。

1. 准备工作

你需要去高德开放平台腾讯位置服务各搞一个开发者账号(具体是搞高德、腾讯还是两个都搞取决于你选择哪个方案),认证,来到如下界面。

然后在应用管理创建一个应用,添加一个 Key。

类型是 Web 服务,申请到之后保存好 Key。

腾讯位置服务那边,则是应用管理我的应用创建应用,然后新建一个 Key,类型选 WebServiceAPI

2. 添加小工具

2.1. 纯高德方案

话不多说,先把代码撂这了:

<?php
function get_user_ip() {
    // 获取用户 IP 地址
    return $_SERVER['REMOTE_ADDR'];
}

function get_adcode_from_ip($api_key, $ip) {
    $ip_url = "https://restapi.amap.com/v3/ip?key={$api_key}&ip={$ip}";
    $response = wp_remote_get($ip_url);
    $data = json_decode(wp_remote_retrieve_body($response), true);

    if ($data['status'] === '1' && isset($data['adcode'])) {
        return $data['adcode'];
    }
    
    return false;
}

function get_weather_data($api_key, $adcode) {
    $weather_url = "https://restapi.amap.com/v3/weather/weatherInfo?key={$api_key}&city={$adcode}";
    $response = wp_remote_get($weather_url);
    $data = json_decode(wp_remote_retrieve_body($response), true);

    if ($data['status'] === '1' && isset($data['lives'][0])) {
        return $data['lives'][0];
    }

    return false;
}

function current_weather_shortcode() {
    $api_key = 'YOUR_AMAP_APPLICATION_KEY'; // 高德 API Key
    $ip = get_user_ip();

    // 检查是否有缓存的数据
    $cached_weather = get_transient('weather_' . $ip);
    
    if ($cached_weather === false) {
        $adcode = get_adcode_from_ip($api_key, $ip);
        // $adcode = isset($adcode) ? $adcode : '441400'; // 默认广东

        if (!$adcode) {
            return "无法获取当前位置。<br>IP: {$ip}";
        }

        // 没有缓存或缓存已过期,获取新的天气数据
        $weather_data = get_weather_data($api_key, $adcode);

        if (!$weather_data) {
            return "天气信息获取失败。<br>IP: {$ip}";
        }

        // 将获取的天气数据缓存10分钟
        set_transient('weather_' . $ip, $weather_data, 30 * MINUTE_IN_SECONDS);

    } else {
        // 使用缓存数据
        $weather_data = $cached_weather;
    }

    // 提取天气信息
    $city = $weather_data['city'];
    $temperature = isset($weather_data['temperature']) ? $weather_data['temperature'] : 'NaN';
    $winddirection = isset($weather_data['winddirection']) ? $weather_data['winddirection'] : '未知';
    $weather = isset($weather_data['weather']) ? $weather_data['weather'] : '未定义';

    $info = "{$temperature}°C,{$winddirection}风";
    $other = "{$city} {$weather}";

    // 处理短代码返回
    ob_start();
    ?>
    <div class="current-weather">
        <p class="info"><?php echo esc_html($info); ?></p>
        <p class="sub"><?php echo esc_html($other); ?></p>
    </div>
    <?php
    return ob_get_clean();
}

add_shortcode('current_weather', 'current_weather_shortcode');
?>

2.2. 高德腾讯混合

由于高德的 IP 定位属实太烂,既不能支持 IPv6 准度也不够,于是后面找了腾讯的,但是腾讯的 API 限频太严格,于是诞生了这么个高德 + 腾讯双合作的方案。

<?php
function get_user_ip() {
    // 获取用户 IP 地址
    return $_SERVER['REMOTE_ADDR'];
}

function get_adcode_from_ip($api_key, $ip) {
    $ip_url = "https://apis.map.qq.com/ws/location/v1/ip?key={$api_key}&ip={$ip}";
    $response = wp_remote_get($ip_url);
    $data = json_decode(wp_remote_retrieve_body($response), true);

    if ($data['status'] === 0 && isset($data['result']['ad_info']['adcode'])) {
        return $data['result']['ad_info']['adcode'];
    }
    
    return false;
}

function get_weather_data($api_key, $adcode) {
    $weather_url = "https://restapi.amap.com/v3/weather/weatherInfo?key={$api_key}&city={$adcode}";
    $response = wp_remote_get($weather_url);
    $data = json_decode(wp_remote_retrieve_body($response), true);

    if ($data['status'] === '1' && isset($data['lives'][0])) {
        return $data['lives'][0];
    }

    return false;
}

function current_weather_shortcode() {
    $tencent_api_key = 'YOUR_TENCENT_APPLICATION_KEY'; // 腾讯 API Key
    $amap_api_key = 'YOUR_AMAP_APPLICATION_KEY'; // 高德 API Key
    $ip = get_user_ip();

    // 检查是否有缓存的数据
    $cached_weather = get_transient('weather_' . $ip);
    
    if ($cached_weather === false) {
        $adcode = get_adcode_from_ip($tencent_api_key, $ip);
        // $adcode = isset($adcode) ? $adcode : '441400'; // 默认广东

        if (!$adcode) {
            return "无法获取当前位置。<br>IP: {$ip}";
        }

        // 没有缓存或缓存已过期,获取新的天气数据
        $weather_data = get_weather_data($amap_api_key, $adcode);

        if (!$weather_data) {
            return "天气信息获取失败。<br>Location: {$adcode}<br>IP: {$ip}";
        }

        // 将获取的天气数据缓存10分钟
        set_transient('weather_' . $ip, $weather_data, 30 * MINUTE_IN_SECONDS);

    } else {
        // 使用缓存数据
        $weather_data = $cached_weather;
    }

    // 提取天气信息
    $city = $weather_data['city'];
    $temperature = isset($weather_data['temperature']) ? $weather_data['temperature'] : 'NaN';
    $winddirection = isset($weather_data['winddirection']) ? $weather_data['winddirection'] : '未知';
    $weather = isset($weather_data['weather']) ? $weather_data['weather'] : '未定义';

    $info = "{$temperature}°C,{$winddirection}风";
    $other = "{$city} {$weather}";

    // 处理短代码返回
    ob_start();
    ?>
    <div class="current-weather">
        <p class="info"><?php echo esc_html($info); ?></p>
        <p class="sub"><?php echo esc_html($other); ?></p>
    </div>
    <?php
    return ob_get_clean();
}

add_shortcode('current_weather', 'current_weather_shortcode');
?>

2.3. 纯腾讯方案

如果您有一个限额比较高的腾讯 API Key,也可以考虑下方的纯腾讯方案:

<?php
function get_user_ip() {
    // 获取用户 IP 地址
    return $_SERVER['REMOTE_ADDR'];
}

function get_adcode_from_ip($api_key, $ip) {
    $ip_url = "https://apis.map.qq.com/ws/location/v1/ip?key={$api_key}&ip={$ip}";
    $response = wp_remote_get($ip_url);
    $data = json_decode(wp_remote_retrieve_body($response), true);

    if ($data['status'] === 0 && isset($data['result']['ad_info']['adcode'])) {
        return $data['result']['ad_info']['adcode'];
    }
    
    return false;
}

function get_weather_data($api_key, $adcode) {
    $weather_url = "https://apis.map.qq.com/ws/weather/v1/?key={$api_key}&adcode={$adcode}";
    $response = wp_remote_get($weather_url);
    $data = json_decode(wp_remote_retrieve_body($response), true);

    if ($data['status'] === 0 && isset($data['result']['realtime'][0]) && isset($data['result']['realtime'][0]['infos'])) {
        return $data['result']['realtime'][0];
    }

    return false;
}

function current_weather_shortcode() {
    $api_key = 'YOUR_TENCENT_APPLICATION_KEY'; // 腾讯 API Key
    $ip = get_user_ip();

    // 检查是否有缓存的数据
    $cached_weather = get_transient('weather_' . $ip);
    
    if ($cached_weather === false) {
        $adcode = get_adcode_from_ip($api_key, $ip);
        // $adcode = isset($adcode) ? $adcode : '441400'; // 默认广东

        if (!$adcode) {
            return "无法获取当前位置。<br>IP: {$ip}";
        }

        // 没有缓存或缓存已过期,获取新的天气数据
        $weather_data = get_weather_data($api_key, $adcode);

        if (!$weather_data) {
            return "天气信息获取失败。<br>Location: {$adcode}<br>IP: {$ip}";
        }

        // 将获取的天气数据缓存10分钟
        set_transient('weather_' . $ip, $weather_data, 30 * MINUTE_IN_SECONDS);

    } else {
        // 使用缓存数据
        $weather_data = $cached_weather;
    }

    // 提取天气信息
    $city = $weather_data['city'];
    $details = $weather_data['infos'];
    $temperature = isset($details['temperature']) ? $details['temperature'] : 'NaN';
    $wind_direction = isset($details['wind_direction']) ? $details['wind_direction'] : '未知';
    $weather = isset($info['weather']) ? $info['weather'] : '未定义';

    $info = "{$temperature}°C,{$wind_direction}风";
    $other = "{$city} {$weather}";

    // 处理短代码返回
    ob_start();
    ?>
    <div class="current-weather">
        <p class="info"><?php echo esc_html($info); ?></p>
        <p class="sub"><?php echo esc_html($other); ?></p>
    </div>
    <?php
    return ob_get_clean();
}

add_shortcode('current_weather', 'current_weather_shortcode');
?>

2.4. 使用

上面的三个方案,随便选择一个,使用 WPCode 或者修改 functions.php 把上面的代码放进去。然后,通过别的手段,把下面这段 CSS 也放进去。

.current-weather {
    text-align: center;
}

.current-weather .info {
    font-size: 1.8em;
    font-weight: bold;
}

.current-weather .sub {
    font-size: 1.2em;
    font-weight: bold;
}

我使用的是 WPCode,所以把这两个东西丢进 Snippets 就好了。

3. 实际效果

这就是实际效果。因为本人能力所限,就只能做到这个视觉效果了。
如果读者有更好的方案,或者修改出一个更好的版本,欢迎在评论区留下您的作品。

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇