热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

PHP1讲座:PHP微信公众平台开发-天气预报功能开发

前面几篇文章对PHP微信公众平台的开通及简单使用做了简单的介绍,但都没有涉及到实际使用中的问题,例如天气查询,公交查询,快递查询等。接下来的几篇文章将对实际生活中会经常使用到的一些功能进行开发讲解,以供读者参考

一、简介

前面几篇文章对PHP微信公众平台的开通及简单使用做了简单的介绍,但都没有涉及到实际使用中的问题,例如天气查询,公交查询,快递查询等。接下来的几篇文章将对实际生活中会经常使用到的一些功能进行开发讲解,以供读者参考。

这一篇文章将对大家每天都会关心的天气查询进行开发,例如,用户发送消息 “苏州天气”,则会返回苏州实时天气状况,以及未来两天甚至未来五天的天气状况。

二、思路分析

首先要对用户发送过来的消息进行判断,判断消息里是否含有“天气”关键字,如果含有,则需要继续提取地区信息,然后再通过中国天气网(http://www.weather.com.cn)提供的开放API进行相关地区天气查询。

三、关键字判断与地区读取

用户发送过来查询天气的消息的格式是固定好的,即 “地区+天气”,所以首先截取后两个字,判断是否为 “天气” 关键字。

使用php函数 mb_substr() 截取,关于该函数的用法:

mb_substr — 获取字符串的部分

  string mb_substr ( string $str , int $start [, int $length [, string $encoding ]] ) 说明:根据字符数执行一个多字节安全的 substr() 操作。 位置是从 str 的开始位置进行计数。 第一个字符的位置是 0。第二个字符的位置是 1,以此类推。 参数: str
从该 string 中提取子字符串。

start
str 中要使用的第一个字符的位置。
正数 -> 从字符串开头指定位置开始;
负数 -> 从字符串结尾指定位置开始;

length
str 中要使用的最大字符数。
正数 -> 从 start 处开始最多包括 length 个字符;
负数 -> string 末尾处的 length 个字符将会被漏掉(若 start 是负数则从字符串开头算起)。  encoding
encoding 参数为字符编码。如果省略,则使用内部字符编码。 返回值: mb_substr() 函数根据 start 和 length 参数返回 str 中指定的部分。

$str = mb_substr($keyword,-2,2,"UTF-8");

从消息的结尾数第二个字符开始截取,截取两个字符,然后加以判断是否为 “天气” 关键字。

下面进行地区提取,还是使用 mb_substr() 函数。

$str_key = mb_substr($keyword,0,-2,"UTF-8");

从消息的开头开始,截掉末尾的两个字符(天气),既得地区关键字。

然后进行判断,继而调用函数查询天气数据。

if($str == '天气' && !empty($str_key))
{ //调用函数查询天气数据 }

四、调用 weather() 函数查询

我们这里调用的是中国国家气象局提供的天气预报API接口,接口地址:http://m.weather.com.cn/data/101190401.html

URL中的数字指代城市的编号101190401(苏州),其他城市对应关系将在下面提供。

该接口返回信息比较全面,也是以json格式提供,格式如下:

{"weatherinfo":{ //基本信息; "city":"苏州","city_en":"suzhou",
"date_y":"2013年7月9日","date":"","week":"星期二","fchh":"18","cityid":"101190401", //摄氏温度 "temp1":"30℃~37℃",
"temp2":"30℃~37℃",
"temp3":"29℃~35℃",
"temp4":"27℃~33℃",
"temp5":"27℃~31℃",
"temp6":"27℃~35℃", //华氏温度; "tempF1":"86℉~98.6℉",
"tempF2":"86℉~98.6℉",
"tempF3":"84.2℉~95℉",
"tempF4":"80.6℉~91.4℉",
"tempF5":"80.6℉~87.8℉",
"tempF6":"80.6℉~95℉", //天气描述; "weather1":"晴转多云",
"weather2":"晴转多云",
"weather3":"晴转多云",
"weather4":"多云",
"weather5":"雷阵雨转中雨",
"weather6":"雷阵雨转多云", //天气描述图片序号 "img1":"0",
"img2":"1",
"img3":"0",
"img4":"1",
"img5":"0",
"img6":"1",
"img7":"1",
"img8":"99",
"img9":"4",
"img10":"8",
"img11":"4",
"img12":"1", //图片名称; "img_single":"1",
"img_title1":"晴",
"img_title2":"多云",
"img_title3":"晴",
"img_title4":"多云",
"img_title5":"晴",
"img_title6":"多云",
"img_title7":"多云",
"img_title8":"多云",
"img_title9":"雷阵雨",
"img_title10":"中雨",
"img_title11":"雷阵雨",
"img_title12":"多云",
"img_title_single":"多云", //风速描述 "wind1":"西南风3-4级",
"wind2":"西南风3-4级",
"wind3":"东南风3-4级",
"wind4":"东南风3-4级转4-5级",
"wind5":"东南风4-5级转西南风3-4级",
"wind6":"西南风3-4级转4-5级", //风速级别描述 "fx1":"西南风",
"fx2":"西南风",
"fl1":"3-4级",
"fl2":"3-4级",
"fl3":"3-4级",
"fl4":"3-4级转4-5级",
"fl5":"4-5级转3-4级",
"fl6":"3-4级转4-5级", //今日穿衣指数; "index":"炎热",
"index_d":"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。", //48小时穿衣指数 "index48":"炎热",
"index48_d":"天气炎热,建议着短衫、短裙、短裤、薄型T恤衫等清凉夏季服装。", //紫外线及48小时紫外线 "index_uv":"中等",
"index48_uv":"中等", //洗车指数 "index_xc":"适宜", //旅游指数 "index_tr":"较不宜", //舒适指数 "index_co":"很不舒适",
"st1":"36",
"st2":"28",
"st3":"36",
"st4":"28",
"st5":"34",
"st6":"27", //晨练指数 "index_cl":"较适宜", //晾晒指数 "index_ls":"适宜", //过敏指数 "index_ag":"不易发"}}

我们可以通过解析JSON,获取相应城市的天气数据。

weather() 函数如下:

private function weather($n){ include("weather_cityId.php"); $c_name=$weather_cityId[$n]; if(!empty($c_name)){ $json=file_get_contents("http://m.weather.com.cn/data/".$c_name.".html"); return json_decode($json);
    } else { return null;
    }
}

这里include 了一个城市对应关系文件 weather_cityId.php,格式如下:

php $weather_cityId = array("北京"=>"101010100","上海"=>"101020100","苏州"=>"101190401"); ?>

根据传入的城市名,得到城市代码,如果不为空,则调用中国天气网的API进行查询,返回json格式的数据,然后进行解析并返回数据,如果为空,则返回null值。

五、组织回复消息形式

判断返回数据是否为空,若为空,则 $cOntentStr= "抱歉,没有查到\"".$str_key."\"的天气信息!";

若返回数据不为空,则:

$cOntentStr= "【".$data->weatherinfo->city."天气预报】\n".$data->weatherinfo->date_y." ".$data->weatherinfo->fchh."时发布"."\n\n实时天气\n".$data->weatherinfo->weather1." ".$data->weatherinfo->temp1." ".$data->weatherinfo->wind1."\n\n温馨提示:".$data->weatherinfo->index_d."\n\n明天\n".$data->weatherinfo->weather2." ".$data->weatherinfo->temp2." ".$data->weatherinfo->wind2."\n\n后天\n".$data->weatherinfo->weather3." ".$data->weatherinfo->temp3." ".$data->weatherinfo->wind3;

说明:

$data->weatherinfo->city  //获取城市名,这里为苏州

$data->weatherinfo->date_y  //获取日期,这里为2013年7月9日

$data->weatherinfo->fchh  //数据发布时间

$data->weatherinfo->weather1  //实时天气

$data->weatherinfo->temp1  //实时温度

$data->weatherinfo->wind1  //实时风向和风速

$data->weatherinfo->index_d  //穿衣指数

weather2, temp2, wind2 分别代表了明天的天气,温度和风向风速,其他的以此类推。

\n  //表示换行

六、测试

七、完整代码

php /**
  * wechat php test */ //define your token define("TOKEN", "zhuojin"); $wechatObj = new wechatCallbackapiTest(); $wechatObj->responseMsg(); //$wechatObj->valid(); class wechatCallbackapiTest
{ /*public function valid()
    {
        $echoStr = $_GET["echostr"];

        //valid signature , option
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }*/ public function responseMsg()
    { //get post data, May be due to the different environments $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //extract post data if (!empty($postStr)){ $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $RX_TYPE = trim($postObj->MsgType); switch($RX_TYPE)
                { case "text": $resultStr = $this->handleText($postObj); break; case "event": $resultStr = $this->handleEvent($postObj); break; default: $resultStr = "Unknow msg type: ".$RX_TYPE; break;
                } echo $resultStr;
        }else { echo ""; exit;
        }
    } public function handleText($postObj)
    { $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $keyword = trim($postObj->Content); $time = time(); $textTpl = "
                    
                    
                    %s
                    
                    
                    0
                    "; if(!empty( $keyword ))
        { $msgType = "text"; //天气 $str = mb_substr($keyword,-2,2,"UTF-8"); $str_key = mb_substr($keyword,0,-2,"UTF-8"); if($str == '天气' && !empty($str_key)){ $data = $this->weather($str_key); if(empty($data->weatherinfo)){ $contentStr = "抱歉,没有查到\"".$str_key."\"的天气信息!";
                } else { $contentStr = "【".$data->weatherinfo->city."天气预报】\n".$data->weatherinfo->date_y." ".$data->weatherinfo->fchh."时发布"."\n\n实时天气\n".$data->weatherinfo->weather1." ".$data->weatherinfo->temp1." ".$data->weatherinfo->wind1."\n\n温馨提示:".$data->weatherinfo->index_d."\n\n明天\n".$data->weatherinfo->weather2." ".$data->weatherinfo->temp2." ".$data->weatherinfo->wind2."\n\n后天\n".$data->weatherinfo->weather3." ".$data->weatherinfo->temp3." ".$data->weatherinfo->wind3;
                }
            } else { $contentStr = "感谢您关注【卓锦苏州】"."\n"."微信号:zhuojinsz"."\n"."卓越锦绣,名城苏州,我们为您提供苏州本地生活指南,苏州相关信息查询,做最好的苏州微信平台。"."\n"."目前平台功能如下:"."\n"."【1】 查天气,如输入:苏州天气"."\n"."【2】 查公交,如输入:苏州公交178"."\n"."【3】 翻译,如输入:翻译I love you"."\n"."【4】 苏州信息查询,如输入:苏州观前街"."\n"."更多内容,敬请期待...";
            } $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); echo $resultStr;
        }else{ echo "Input something...";
        }
    } public function handleEvent($object)
    { $contentStr = ""; switch ($object->Event)
        { case "subscribe": $contentStr = "感谢您关注【卓锦苏州】"."\n"."微信号:zhuojinsz"."\n"."卓越锦绣,名城苏州,我们为您提供苏州本地生活指南,苏州相关信息查询,做最好的苏州微信平台。"."\n"."目前平台功能如下:"."\n"."【1】 查天气,如输入:苏州天气"."\n"."【2】 查公交,如输入:苏州公交178"."\n"."【3】 翻译,如输入:翻译I love you"."\n"."【4】 苏州信息查询,如输入:苏州观前街"."\n"."更多内容,敬请期待..."; break; default : $contentStr = "Unknow Event: ".$object->Event; break;
        } $resultStr = $this->responseText($object, $contentStr); return $resultStr;
    } public function responseText($object, $content, $flag=0)
    { $textTpl = "
                    
                    
                    %s
                    
                    
                    %d
                    "; $resultStr = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content, $flag); return $resultStr;
    } private function weather($n){ include("weather_cityId.php"); $c_name=$weather_cityId[$n]; if(!empty($c_name)){ $json=file_get_contents("http://m.weather.com.cn/data/".$c_name.".html"); return json_decode($json);
        } else { return null;
        }
    } private function checkSignature()
    { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true;
        }else{ return false;
        }
    }
} ?>

关于城市对应关系文件 weather_cityId.php,目前更新到了2564个城市,以后还会继续增加,请到 乐思乐享 官方论坛(URL:http://www.joythink.net/)下载吧。
 




推荐阅读
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 在Android中解析Gson解析json数据是很方便快捷的,可以直接将json数据解析成java对象或者集合。使用Gson解析json成对象时,默认将json里对应字段的值解析到java对象里对应字段的属性里面。然而,当我们自己定义的java对象里的属性名与json里的字段名不一样时,我们可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。本文介绍了使用@SerializedName注解解析json数据的方法,并给出了具体的使用示例。 ... [详细]
  • Monkey《大话移动——Android与iOS应用测试指南》的预购信息发布啦!
    Monkey《大话移动——Android与iOS应用测试指南》的预购信息已经发布,可以在京东和当当网进行预购。感谢几位大牛给出的书评,并呼吁大家的支持。明天京东的链接也将发布。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 使用在线工具jsonschema2pojo根据json生成java对象
    本文介绍了使用在线工具jsonschema2pojo根据json生成java对象的方法。通过该工具,用户只需将json字符串复制到输入框中,即可自动将其转换成java对象。该工具还能解析列表式的json数据,并将嵌套在内层的对象也解析出来。本文以请求github的api为例,展示了使用该工具的步骤和效果。 ... [详细]
  • jmeter实践:从csv中获取带引号的数据详情的技巧和运行全部数据的方法
    本文分享了jmeter实践中从csv中获取带引号的数据的解决办法,包括设置CSV Data Set Config和运行脚本获取数据的方法。另外还介绍了循环运行csv中全部数据的解决方法,避免每次修改csv用例都需要修改脚本的麻烦。通过了解和掌握工具的细节点,可以更好地解决问题和提高技术水平。 ... [详细]
  • 数字账号安全与数据资产问题的研究及解决方案
    本文研究了数字账号安全与数据资产问题,并提出了解决方案。近期,大量QQ账号被盗事件引起了广泛关注。欺诈者对数字账号的价值认识超过了账号主人,因此他们不断攻击和盗用账号。然而,平台和账号主人对账号安全问题的态度不正确,只有用户自身意识到问题的严重性并采取行动,才能推动平台优先解决这些问题。本文旨在提醒用户关注账号安全,并呼吁平台承担起更多的责任。令牌云团队对此进行了长期深入的研究,并提出了相应的解决方案。 ... [详细]
  • 单点登录原理及实现方案详解
    本文详细介绍了单点登录的原理及实现方案,其中包括共享Session的方式,以及基于Redis的Session共享方案。同时,还分享了作者在应用环境中所遇到的问题和经验,希望对读者有所帮助。 ... [详细]
  • 使用正则表达式爬取36Kr网站首页新闻的操作步骤和代码示例
    本文介绍了使用正则表达式来爬取36Kr网站首页所有新闻的操作步骤和代码示例。通过访问网站、查找关键词、编写代码等步骤,可以获取到网站首页的新闻数据。代码示例使用Python编写,并使用正则表达式来提取所需的数据。详细的操作步骤和代码示例可以参考本文内容。 ... [详细]
  • 企业数据应用挑战及元数据管理的重要性
    本文主要介绍了企业在日常经营管理过程中面临的数据应用挑战,包括数据找不到、数据读不懂、数据不可信等问题。针对这些挑战,通过元数据管理可以实现数据的可见、可懂、可用,帮助业务快速获取所需数据。文章提出了“灵魂”三问——元数据是什么、有什么用、又该怎么管,强调了元数据管理在企业数据治理中的基础和前提作用。 ... [详细]
  • 小程序自动授权和手动接入的方式及操作步骤
    本文介绍了小程序支持的两种接入方式:自动授权和手动接入,并详细说明了它们的操作步骤。同时还介绍了如何在两种方式之间切换,以及手动接入后如何下载代码包和提交审核。 ... [详细]
author-avatar
H-蔡鸿晖_515
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有