【php】微信公众平台接口开发--点歌

一、引言与说明

目前很多公众帐号都可以实现点歌功能,笔者也很好奇是如何实现的,就做了个实验,现将经验分享如下。

有关音乐消息的说明,就不在此赘述,请自行查阅开发文档。

回复音乐消息的关键在于如何获得歌曲的链接,开发者必须找一个现成的音乐搜索API(对大多数开发者都不太可能有自己的音乐服务器),或者只向用户回复固定的几首音乐,可以定期手动更新[1](参考)。

百度有一个私有的音乐搜索API。开发者可以直接调用,地址如下:

http://box.zhangmen.baidu.com/x?op=12&count=1&title=Song$$Singer$$$$

开发者只需要提供歌名和歌手就可搜索到指定音乐(歌手可以为空)。在浏览器中输入该地址可以得道以下信息:

<result>
<count>1</count>
<url>
<encode>
http://zhangmenshiting.baidu.com/data2/music/64380827/Z2ZmbGVuaW9fn6NndK6ap5WXcGZlbm-aYpNol2ppm5xjamRtbpttbWeVlpdrmGlrkpNomZaXa3CTZJeZmW1ncGVll1qin5t1YWBnZWVoam5hZWNqZ2hnaTE$
</encode>
<decode>
64380827.mp3?xcode=2088b1a5c53dd28199e656ccc6b23aa5eaa48b2ded70843d&mid=0.41023603062201
</decode>
<type>8</type>
<lrcid>14706</lrcid>
<flag>1</flag>
</url>
<durl>
<encode>http://zhangmenshiting2.baidu.com/data2/music/35424427/ZGdnZmlqaW9fn6NndK6ap5WXcGZlbm-aYpNol2ppm5xjamSWm5qbaGaWZWyXbm2dampsbGqca5mVZ5iWlmxwnGJmZlqin5t1YWBnZWVoam5hZWNqZ2hnaTE$
</encode>
<decode>
35424427.mp3?xcode=2088b1a5c53dd281bfdd05d28b86e98985f4ad5eba69d143&mid=0.41023603062201
</decode>
<type>8</type>
<lrcid>14706</lrcid>
<flag>1</flag>
</durl>
<p2p>
<hash>d1cae9f7634c5aa3d54d7b1b1ad4c5b79b6e97ff</hash>
<url></url>
<type>mp3</type>
<size>5710896</size>
<bitrate>192</bitrate>
</p2p>
</result>
有关各项参数的意义[2]:

1)<count> 表示搜索到的音乐数;

2)<url>中包含了普通品质的音乐链接,<durl>中包含了高品质音乐的链接;

3)<encode>中包含了加密后的音乐链接,实际上只是对音乐名称进行了加密,<decode>中包含了解密后的音乐名称。因此,要获取音乐的链接就需要重点分析<encode>和<decode>中的内容

4)<type>表示音乐文件的类型,如rm、wma、mp3等;

5)<lrcid>是歌词的ID.

二、关键代码

开发者需要对<url>中的链接进行进一步的处理,才能写入公众平台的消息中。请看php代码:

/*
 * 所属类:apiFunction
 * 函数名:baiduMusic()
 * 参数:
 * 功能:调用百度音乐api,推送音乐
 */
	public function baiduMusic($Song, $Singer)
	{
		if (!empty($Song))
		{
			//音乐链接有两中品质,普通品质和高品质
			$music = array (
				‘url‘ => "",
				‘durl‘ => "");

			//采用php函数file_get_contents来读取链接内容
			$file = file_get_contents("http://box.zhangmen.baidu"
				.".com/x?op=12&count=1&title=".$Song."$$".$Singer."$$$$");

			//simplexml_load_string() 函数把 XML 字符串载入对象中
			$xml = simplexml_load_string($file, 
				‘SimpleXMLElement‘, LIBXML_NOCDATA);

			//如果count大于0,表示找到歌曲
			if ($xml->count > 0)
			{
				//普通品质音乐
				$encode_str = $xml->url->encode;

				//使用正则表达式,进行字符串匹配,处理网址
				preg_match("/http:\/\/([\w+\.]+)(\/(\w+\/)+)/", $encode_str, $matches);

				//第一个匹配的就是我们需要的字符串
				$url_parse = $matches[0];

				$decode_str = $xml->url->decode;

				//分离字符串,截去mid
				$decode_arr = explode(‘&‘, $decode_str);

				//拼接字符串,获得普通品质音乐
				$musicUrl = $url_parse.$decode_arr[0];


				//高品质音乐
				$encode_dstr = $xml->durl->encode;
				preg_match("/http:\/\/([\w+\.]+)(\/(\w+\/)+)/", $encode_dstr, $matches_d);

				//第一个匹配的就是我们需要的字符串
				$durl_parse = $matches_d[0];

				$decode_dstr = $xml->durl->decode;
				//分离字符串,截去mid
				$decode_darr = explode(‘&‘, $decode_dstr);

				//拼接字符串,获得高品质音乐
				$musicDurl = $durl_parse.$decode_darr[0];

				//将两个链接放入数组中
				$music = array(
					‘url‘ => $musicUrl,
					‘durl‘ => $musicDurl
				);
				return $music;

			}

			return $music;
		}
		else
		{
			$music = "";
			return $music;
		}

	}


重点解释下preg_match这条语句

preg_match("/http:\/\/([\w+\.]+)(\/(\w+\/)+)/", $encode_str, $matches);

preg_match执行一个正则表达式匹配,原型如下:

int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )
按照pattern给定的正则表达式模式,搜索subjectpattern的一个匹配。结果保存在array $matches中。

pattern的语法为--"/ /",如:"/php/".

http:是链接开头,\表示转义,\/表示/,\/\/表示//

第一个括号([\w+\.]+):

             圆括号表示匹配括号内模式,并获取该字符串。

             []表示字符集合,例如, ‘[abc]‘ 可以匹配 "plain" 中的 ‘a‘。\w表示匹配包括下划线的任何单词字符。等价于‘[A-Za-z0-9_]‘

             +表示匹配前面的子表达式一次或多次

             \.表示 .

      第一个括号匹配的结果为http://zhangmenshiting.baidu.com

第二个括号(\/(\w+\/)+)

              \/表示/

              (\w+\/)表示匹配 ’music/‘ 这样的字符串

              +表示匹配前面的子表达式一次或多次

       第二个括号匹配结果为/data2/music/64380827/

这两段字符串连起来就是所需要的字符串,保存在$matches中

三、调用

在处理文本消息函数中,调用

		/* 点歌,百度API  */
			$str_music = mb_substr($keyword, 0, 1, "UTF-8");
			$str_explode = mb_substr($keyword, 1, 20, "UTF-8");
			$req_music = explode(‘#|#‘, $str_explode);
			//$song = mb_substr($keyword, 1, 220, "UTF-8");
			$song = $req_music[0];
			$singer = $req_music[1];

			if ($str_music == ‘#‘ || $str_music == ‘#‘)
			{
				if ($str_valid == ‘#‘ || $str_valid == ‘#‘)
				{
					$contentStr = "输入格式不正确哦".
					"点歌请输入:#+歌名 或者 #+歌名+#+歌手";
				}
				else
				{
					$url_arr = $apiFunc->baiduMusic($song, $singer);
					if (empty($url_arr))
					{
						$contentStr = "非常抱歉哦,小和尚".
							"没有找到这首歌,可以换一首嘛[微笑]";
					}
					else
					{
						include("wx_tpl.php");
						
						$resultStr = sprintf(
								$musicTpl, 
								$object->FromUserName,
								$object->ToUserName, 
								$song,
							        $singer,	
								$url_arr[‘url‘],
								$url_arr[‘durl‘]
								);
						return $resultStr;
				  
					}
				}

			}
首先对关键字进行处理并判断。如果第一个字是以“#”开头,表示点歌。全角或半角都可以。

explode函数对字符串进行分隔,将分隔后结果保存在数组中,在将数组值赋给变量$Song、$Singer。

参考文献:


[1]青龙老贼:《微信公众平台入门到精通》Vol.11

[2] [042] 微信公众帐号开发教程第18篇-应用实例之音乐搜索


转帖请注明本文出自bsdcfp的专栏,请尊重他人的辛勤劳动成果,谢谢!

【php】微信公众平台接口开发--点歌

上一篇:【直播回顾】云栖社区特邀专家户庆凯:JVM的GC(垃圾回收器)机制


下一篇:阿里云Link ID² 安全领域再拿殊荣