前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Laravel学习记录--微信开发(day1)

Laravel学习记录--微信开发(day1)

作者头像
切图仔
发布2022-09-08 19:40:25
1.1K0
发布2022-09-08 19:40:25
举报
文章被收录于专栏:生如夏花绚烂

上一篇文章中我们介绍了微信开发的准备工作接下来就是正式开发了

以自动回复为例

要实现自动回复,我们首先的获取用户输入的消息,那么怎么获取用户输入的数据 根据文档,“消息管理”----“接收普通消息” 注意这样一句话

“当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

当普通用户发送消息到公众号时,微信服务器会发送POST请求到我们的服务器,包含一个XML的数据包

XMLJSON一样都是通用的数据类型 既然是发送POST请求,那我们是不是可以用$_POST接收数据?

尝试一下 首先关注我们这个测试公众号 “开发者工具----公众平台测试账号”,下拉鼠标有个测试二维码,扫码并关注 接下来的开发都基于此账号

本地服务器接收数据

代码语言:javascript
复制
$txt = $_POST['Content'];
//这里我们只接收用户发送的消息,并将其存放到1.txt文件
file_put_contents('./1.txt', $txt);

打开1.txt发现什么也没有

在这里插入图片描述
在这里插入图片描述

什么原因?原来$_POST是不能接收test/xml的数据类型(具体为什么不能可参照POST和$GLOBALS[‘HTTP_RAW_POST_DATA’] 的区别,在前面我们提到,微信服务器将用户的消息,以xml的格式发送给本地服务器。

在php5.6以前我们可以通过GLOBALS['HTTP_RAW_POST_DATA']接收POST不能接受的数据,但在php7.0后这个方法被废弃,php7.0后我们可以使用

file_get_contents('php://input')获取原生的POST数据。

了解了这个后修改我们的代码

代码语言:javascript
复制
$txt = file_get_contents('php://input');
file_put_contents('./1.txt', $txt);

打开1.txt发现被写入了一段xml数据

代码语言:javascript
复制
<xml><ToUserName><![CDATA[gh_811767743479]]></ToUserName>
<FromUserName><![CDATA[oYRMeuO7pFQP-jXLTE2YmEVCAhPg]]></FromUserName>
<CreateTime>1580781691</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[热]]></Content>//用户发送的消息
<MsgId>22631351498653850</MsgId>
</xml>

Content就是用户发送的消息

虽然获取到了,但我们怎么处理他?在php看来上面这些就是一字符串,这里我们就要像使用json数据那样,将xml数据转换为php对象 php为我们提供了函数将xml数据转换为php对象

代码语言:javascript
复制
simplexml_load_string($postStr,'SimpleXMLElement',LIBXML_NOCDATA);

修改我们的代码

代码语言:javascript
复制
$txt = file_get_contents('php://input');
//XML数据转换为php对象
$txtObj = simplexml_load_string($txt,'SimpleXMLElement',LIBXML_NOCDATA);
file_put_contents('./1.txt', $txtObj->Content);

发送消息

打开1.txt文件

接受用户信息成功 接受信息之后我们设置自动回复返回给用户消息 查看文档“消息管理----被动回复用户消息”`

当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。严格来说,发送被动响应消息其实并不是一种接口,而是对微信服务器发过来消息的一次回复。

既然接受是xml数据包,那回复肯定也是xml数据 编辑我们的代码,判断用户回复消息

代码语言:javascript
复制
<?php

//服务器验证
//接收参数

    $txt = file_get_contents('php://input');
    $txtObj = simplexml_load_string($txt,'SimpleXMLElement',LIBXML_NOCDATA);

    //消息发送模板
    $txtModel = "
                <xml>
                <ToUserName><![CDATA[%s]]></ToUserName>
                <FromUserName><![CDATA[%s]]></FromUserName>
                <CreateTime>%s</CreateTime>
                <MsgType><![CDATA[%s]]></MsgType>
               <Content><![CDATA[%s]]></Content>
               </xml>";
    $toUserName = $txtObj->FromUserName;//接受方等于发送此消息的用户名
    $fromUserName = $txtObj->ToUserName;//发送方等用户发送消息的ToUserName
    $time = time();

    if($txtObj->MsgType = 'text'){
        //如果用户回复的是文本消息
        $msgType = 'text';
        if($txtObj->Content == '1'){
            //如果用户回复的是文本“1”
            $content = '测试回复【发送1】!!!';
            $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
            echo $sendText;
            
        }else{
            $content = '测试回复【常规】!!!';
            $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
            echo $sendText;

        }
    }

上述代码通过sprintf进行字符串格式化,这样做的好处是不用重复的写xml格式的数据包,直接将其定义成模板留出占位符,直接调用sprintf填充数据

到此已经完成了简单的自动回复功能

我们还可以根据不同的数据类型进行不同的消息回复

代码语言:javascript
复制
<?php

//服务器验证
//接收参数

    $txt = file_get_contents('php://input');
    $txtObj = simplexml_load_string($txt,'SimpleXMLElement',LIBXML_NOCDATA);

    //消息发送模板
    $txtModel = "
                <xml>
                <ToUserName><![CDATA[%s]]></ToUserName>
                <FromUserName><![CDATA[%s]]></FromUserName>
                <CreateTime>%s</CreateTime>
                <MsgType><![CDATA[%s]]></MsgType>
               <Content><![CDATA[%s]]></Content>
               </xml>";
    $toUserName = $txtObj->FromUserName;//接受方等于发送此消息的用户名
    $fromUserName = $txtObj->ToUserName;//发送方等用户发送消息的ToUserName
    $time = time();
    $msgType = 'text';

    if($txtObj->MsgType == 'text'){
        //如果用户回复的是文本消息

        if($txtObj->Content == '1'){
            //如果用户回复的是文本“1”
            $content = '测试回复【发送1】!!!';
            $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
            echo $sendText;
        }else{
            $content = '测试回复【常规】!!!';
            $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
            echo $sendText;
        }

    }elseif($txtObj->MsgType == 'image'){

        $content = '您发送了一张图片安';
        $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
        echo $sendText;
    }elseif($txtObj->MsgType == 'voice'){
        $content = '您发送了一条语音安';
        $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
        echo $sendText;
    }elseif($txtObj->MsgType == 'video'){
        $content = '您发送了一条视频安';
        $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
        echo $sendText;
    }elseif($txtObj->MsgType == 'location'){
        $content = '您发送了一条位置信息s安';
        $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
        echo $sendText;
    }

完成上述操作后我们已经知道如何获取用户消息,设置自动回复了 接下来完成一个案例 用户发送位置信息查询地图上距离用户当前位置的银行信息 要完成这个案例,肯定的调用第三方地图接口,如百度地图

注册/登录成为其用户,并按照提示邮箱激活 激活后我们选择“控制台”---“应用管理”---“创建应用”

这里我们只需要地点检索 创建完成后,会生成一个“AK”;这个“AK”用于调用接口 点击开发文档-----“web服务API”

选择地点检索服务

服务文档选择找到”圆型区域“

阅读参数,进行相关设置 浏览器地址栏测试访问接口

成功访问,不过这里我们将返回的数据类型设置为‘json’通过设置参数output=json,同时使其返回详细地址通过设置参数scope=2 接下来我们就可以通过php发送get请求到百度地图,使其返回对应的位置信息

代码语言:javascript
复制
http://api.map.baidu.com/place/v2/search?query=%E9%93%B6%E8%A1%8C&location=39.915,116.404&radius=2000&output=json&scope=2&ak=这里键入你的“Ak”

通过file_get_contents函数

代码语言:javascript
复制
if($txtObj->MsgType == 'location'){
        //如果用户发送位置信息
        $latitude = $txtObj->Location_X;//纬度
        $longitude = $txtObj->Location_Y;//经度
        $url = 'http://api.map.baidu.com/place/v2/search?query=银行&location='.$latitude.','.$longitude.'&radius=2000&output=json&scope=2&ak='.$ak
        $arr = file_get_contents($url);//发送get请求
        $arrPosition = json_decode($arr,true)['results'];//将获取到的结果转换为数组
        $content ="共有".count($arrPosition)."条关于银行的记录\n\n";
        foreach($arrPosition as $key => $value){
            $content.= $value['name'].'在'.$value['province'].$value['city'].$value['area'].$value['address'].'距离你'.$value['detail_info']['distance']."米\n\n";
          
        }
        $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
        echo $sendText;
    }

案例二,人脸识别评估

同样这里要调用第三方接口,通过第三方分析人脸数据并将其返回给用户

1.注册旷视

注册登录后,创建一个应用,生APIKey与APISecret,用于调用他的接口

查看API文档

这里我们选择DeleteApi 仔细阅读文档,查看调用api必选参数与可选参数

调用URL https://api-cn.faceplusplus.com/facepp/v3/detect 调用方法 POST 请求体格式 multipart/form-data

由于要用post的方式请求它,这里我们就用curl 先来测试一下能否访问

代码语言:javascript
复制
<?php

$data = [
    'api_key'=>'dut2DHBMm8reohiFo_Kx17GwIfx0EkW3',
    'api_secret'=>'xBHyvcOxMtXrRwZrNzVAlcU2_mW7bT_Y',
    'image_url'=>'http://590c1c9e.nat123.cc/2.jpg',//图片地址
    'return_landmark'=>'1',
    'return_attributes'=>'gender,age,emotion,beauty'//请求返回数据包含性别,年龄,情绪,颜值
];
$url = 'https://api-cn.faceplusplus.com/facepp/v3/detect';
//1,初始化
$curl = curl_init();
//设置参数
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_HEADER,0);//不返回header头
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//数据返回而不是输出
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);//使用ssl证书加密
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);//post提交
//发送请求信息
$data = curl_exec($curl);
//关闭请求资源
curl_close($curl);
$arr = json_decode($data,true)['faces'];//将返回的数据转换为php数组
print_r($arr);

数据返回成功,接下来对需要的数据进行处理

代码语言:javascript
复制
$data = [
    'api_key'=>'你的APIKEY',
    'api_secret'=>'你的Secret',
    'image_url'=>'http://590c1c9e.nat123.cc/2.jpg',//图片地址
    'return_landmark'=>'1',
    'return_attributes'=>'gender,age,emotion,beauty'//请求返回数据包含性别,年龄,情绪,颜值
];
$url = 'https://api-cn.faceplusplus.com/facepp/v3/detect';
//1,初始化
$curl = curl_init();
//设置参数
curl_setopt($curl, CURLOPT_URL,$url);
curl_setopt($curl, CURLOPT_HEADER,0);//不返回header头
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//数据返回而不是输出
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);//不使用ssl证书加密
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);//post提交
//发送请求信息
$data = curl_exec($curl);
//关闭请求资源
curl_close($curl);

$arr = json_decode($data,true)['faces'];//将返回的数据转换为php数组
$content = "一共检测到".count($arr)."个人物\n";
foreach ($arr as $key => $value) {
    $gender = $value['attributes']['gender']['value']=='Male'?'男':'女';

    $content .= '第'.($key+1)."个的性别为:".$gender.";年龄为:".$value['attributes']['age']['value'].";颜值为:".$value['attributes']['beauty']['male_score']."\n\n";
    
}

echo $content;

这里能显示正常,但放微信上就不行了,估计问题是请求时间过长,超时请求,所以出现了如下问题

代码语言:javascript
复制
$data = [
            'api_key'=>$key,
            'api_secret'=>$secret,
            'image_url'=>'http://590c1c9e.nat123.cc/2.jpg',//图片地址
            'return_landmark'=>'1',
            'return_attributes'=>'gender,age,emotion,beauty'//请求返回数据包含性别,年龄,情绪,颜值
        ];
    $url = 'https://api-cn.faceplusplus.com/facepp/v3/detect';
    //1,初始化
    $curl = curl_init();
    //设置参数
    curl_setopt($curl, CURLOPT_URL,$url);
    curl_setopt($curl, CURLOPT_HEADER,0);//不返回header头
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);//数据返回而不是输出
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0);//使用ssl证书加密
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);//post提交
    //发送请求信息
    $data = curl_exec($curl);
    //关闭请求资源
    curl_close($curl);
    $arr = json_decode($data,true)['faces'];//将返回的数据转换为php数组
    foreach ($arr as $key => $value) {
    $gender = $value['attributes']['gender']['value']=='Male'?'男':'女';

   $content .= '第'.($key+1)."个的性别为:".$gender.";年龄为:".$value['attributes']['age']['value'].";颜值为:".$value['attributes']['beauty']['male_score']."\n\n";
    
    $sendText = sprintf($txtModel,$toUserName,$fromUserName,$time,$msgType,$content);
    echo $sendText;

浏览器直接打开都行,但是访问时间太长

尝试了很多次还是不行......放弃了,但正常情况上面的代码的data数组的image_url应该改成 $txtObj->PicUrl获取用户上传的图片地址,根据图片分析信息并传递给用户

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-05-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
人脸识别
腾讯云神图·人脸识别(Face Recognition)基于腾讯优图强大的面部分析技术,提供包括人脸检测与分析、比对、搜索、验证、五官定位、活体检测等多种功能,为开发者和企业提供高性能高可用的人脸识别服务。 可应用于在线娱乐、在线身份认证等多种应用场景,充分满足各行业客户的人脸属性识别及用户身份确认等需求。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档