最近被逼着用PHP做微信,作为一个干了4年JAVA的人,各种不适应有木有,还好坚持下来,收货多多,今天写篇thinkphp接口的博客,首先必须要有个微信开发者账号,然后要有个域名映射到自己的公网服务器上。
1:在微信官网下载微信接口接触类,所以这就是做PHP的优势官网弄下来就可以用。
<?php
define("TOKEN", "weixin");
class Weixin
{
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);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
if(!empty( $keyword ))
{
$msgType = "text";
$contentStr = "Welcome to wechat world!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
}
?>
将上面这个类放入LIB/ORG下面命名为Weixin.class.php.
2:新建个WeixinAction.class.php继承上面的基础类并且从写关注,取消关注等。
<?php
header("content-type:text/html;charset=utf-8");
class WeixinAction extends Action{
public $wxurl ;
function __construct()
{
$this->wxurl = $_SERVER['SERVER_NAME'].__ROOT__ ;
}
public function wenben($fromUsername, $toUsername, $time, $contentStr)
{
//文本链接的处理/ ///
$str=$contentStr;
$reg = '/\shref=[\'\"]([^\'"]*)[\'"]/i';
preg_match_all($reg , $str , $out_ary);//正则:得到href的地址
$src_ary = $out_ary[1];
if(!empty($src_ary))//存在
{
$comment=$src_ary[0];
if(stristr($comment,$_SERVER['SERVER_NAME']))
{
if(stristr($comment,"?"))
{
$links=$comment."&key=".$fromUsername;
$contentStr= str_replace($comment,$links,$str);
}else
{
$links=$comment."?key=".$fromUsername;
$contentStr= str_replace($comment,$links,$str);
}
}
}
//文本链接的处理 END
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
$msgType = "text";
//$contentStr =$contentStr;
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}
public function tuwen($textTpl,$fromUsername, $toUsername, $time,$count)
{
$msgType = "news";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType,$count);
echo $resultStr;
}
public function index(){
import('Think.ORG.Weixin');// 导入微信类
//traceHttp();
$wechat = new Weixin();
$wechat->valid();
//$wechat->responseMsg();
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($postStr)){
$key_word=M('keyword');
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = trim($postObj->FromUserName);//发送方帐号(一个OpenID)
$toUsername = $postObj->ToUserName;//开发者微信号
$keyword = trim($postObj->Content);//用户发来的信息
$RX_TYPE = trim($postObj->MsgType);//类型
$EventKey=trim($postObj->EventKey);//事件KEY值
$Event=$postObj->Event;//事件类型
$time = time();
if($fromUsername!='')
{
$user= M('user')->field('id,wechatid')->where("wechatid='".$fromUsername."'")->find();
if($user)
{
$this->modFocus($fromUsername,1);
}else
{
$date=time();
$data['username']=$fromUsername;//用户名
$data['wechatid']=$fromUsername;//微信id
$data['reg_time']=$date;
$data['last_time']=$date;
//$userid= M('user')->add($data);
$data['password']=md5($fromUsername);
$userid= M('user')->add($data);
}
}
if($RX_TYPE=='event')
{
//**自定义点击事件**//
if($Event=='CLICK')
{
//这里我是点击菜单菜单没有写链接返回一个图文,点击进入我的微网,主要用于免登陆
if($EventKey!='')
{
$where=array('keyword'=>$EventKey);
$custom_key= M('custom_menu')->where($where)->find();
$key_list= $key_word->where("kyword='".$custom_key['keyword']."'")->find();
//$key_list= $key_word->where("kyword='".$EventKey."'")->find();
if(is_array($key_list))
{
if($key_list['type']==1)//文本
{
$this->wenben($fromUsername, $toUsername, $time,$key_list['kecontent']);
}else //图文
{
$titles = unserialize($key_list['titles']);
$imageinfo = unserialize($key_list['imageinfo']);
$linkinfo = unserialize($key_list['linkinfo']);
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<ArticleCount>%s</ArticleCount>
<Articles>";
for($i=0;$i<count($titles);$i++)
{
if(stristr($linkinfo[$i],$_SERVER['SERVER_NAME']))
{
if(stristr($linkinfo[$i],"?"))
{
$links=$linkinfo[$i]."&key=".$fromUsername;
}else
{
$links=$linkinfo[$i]."?key=".$fromUsername;
}
}else{
$links=$linkinfo[$i];
}
if(stristr($imageinfo[$i],$_SERVER['SERVER_NAME']))
{
$images=$imageinfo[$i];
}else
{
$images="http://".$_SERVER['SERVER_NAME'].__ROOT__.'/'.$imageinfo[$i];
}
$textTpl.= " <item>
<Title><![CDATA[".$titles[$i]."]]></Title>
<Description><![CDATA[".$titles[$i]."]]></Description>
<PicUrl><![CDATA[".$images."]]></PicUrl>
<Url><![CDATA[".$links."]]></Url>
</item>";
/* $textTpl.= " <item>
<Title><![CDATA[".$titles[$i]."]]></Title>
<Description><![CDATA[".$titles[$i]."]]></Description>
<PicUrl><![CDATA[http://".$_SERVER['SERVER_NAME'].__ROOT__.'/'.$imageinfo[$i]."]]></PicUrl>
<Url><![CDATA[".$links."]]></Url>
</item>";*/
}
$textTpl.= "</Articles>
<FuncFlag>0</FuncFlag>
</xml>
";
$this->tuwen($textTpl,$fromUsername, $toUsername, $time,count($titles));
}
}
}
}
if($Event=='unsubscribe')
{
$this->modFocus($fromUsername,0);
}
if($Event=='subscribe')
{
// $this->debugLog("关注","gz");
$this->modFocus($fromUsername,1,1);
$key_list= $key_word->where("isfollow=1")->find();
if(is_array($key_list))//关注时回复
{
// while(list($key,$val)= each($key_list)) {
// $this->debugLog($key."~".$val,"$key_list");
// }
// for ($i= 0;$i< count($key_list); $i++){
// $str= $key_list[$i];
// $this->debugLog($str,"key_list");
// }
// $this->debugLog($key_list['type'],"key_list");
if($key_list['type']==1)//文本
{
$this->wenben($fromUsername, $toUsername, $time,$key_list['kecontent']);
}else //图文
{
$titles = unserialize($key_list['titles']);
$imageinfo = unserialize($key_list['imageinfo']);
$linkinfo = unserialize($key_list['linkinfo']);
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<ArticleCount>%s</ArticleCount>
<Articles>";
for($i=0;$i<count($titles);$i++)
{
if(stristr($linkinfo[$i],$_SERVER['SERVER_NAME']))
{
if(stristr($linkinfo[$i],"?"))
{
$links=$linkinfo[$i]."&key=".$fromUsername;
}else
{
$links=$linkinfo[$i]."?key=".$fromUsername;
}
}else{
$links=$linkinfo[$i];
}
if(stristr($imageinfo[$i],$_SERVER['SERVER_NAME']))
{
$images=$imageinfo[$i];
}else
{
$images="http://".$_SERVER['SERVER_NAME'].__ROOT__.'/'.$imageinfo[$i];
}
$textTpl.= " <item>
<Title><![CDATA[".$titles[$i]."]]></Title>
<Description><![CDATA[".$titles[$i]."]]></Description>
<PicUrl><![CDATA[".$images."]]></PicUrl>
<Url><![CDATA[".$links."]]></Url>
</item>";
}
$textTpl.= "</Articles>
<FuncFlag>0</FuncFlag>
</xml>
";
$this->tuwen($textTpl,$fromUsername, $toUsername, $time,count($titles));
}
}
}
}
//关键字自动回复
if(!empty($keyword))
{
$key_list= $key_word->where("kyword='".$keyword."'")->find();
if(is_array($key_list))
{
if($key_list['type']==1)//文本
{
$this->wenben($fromUsername, $toUsername, $time,$key_list['kecontent']);
}else //图文
{
$titles = unserialize($key_list['titles']);
$imageinfo = unserialize($key_list['imageinfo']);
$linkinfo = unserialize($key_list['linkinfo']);
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<ArticleCount>%s</ArticleCount>
<Articles>";
for($i=0;$i<count($titles);$i++)
{
if(stristr($linkinfo[$i],$_SERVER['SERVER_NAME']))
{
if(stristr($linkinfo[$i],"?"))
{
$links=$linkinfo[$i]."&key=".$fromUsername;
}else
{
$links=$linkinfo[$i]."?key=".$fromUsername;
}
}else{
$links=$linkinfo[$i];
}
if(stristr($imageinfo[$i],$_SERVER['SERVER_NAME']))
{
$images=$imageinfo[$i];
}else
{
$images="http://".$_SERVER['SERVER_NAME'].__ROOT__.'/'.$imageinfo[$i];
}
$textTpl.= " <item>
<Title><![CDATA[".$titles[$i]."]]></Title>
<Description><![CDATA[".$titles[$i]."]]></Description>
<PicUrl><![CDATA[".$images."]]></PicUrl>
<Url><![CDATA[".$links."]]></Url>
</item>";
}
$textTpl.= "</Articles>
<FuncFlag>0</FuncFlag>
</xml>
";
$this->tuwen($textTpl,$fromUsername, $toUsername, $time,count($titles));
}
}else //自动回复
{
$key_list= $key_word->where("ismess=1")->find();
if(is_array($key_list))//是否存在
{
if($key_list['type']==1)//文本
{
$this->wenben($fromUsername, $toUsername, $time, $key_list['kecontent']);
}else //图文
{
$titles = unserialize($key_list['titles']);
$imageinfo = unserialize($key_list['imageinfo']);
$linkinfo = unserialize($key_list['linkinfo']);
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<ArticleCount>%s</ArticleCount>
<Articles>";
for($i=0;$i<count($titles);$i++)
{
if(stristr($linkinfo[$i],$_SERVER['SERVER_NAME']))
{
if(stristr($linkinfo[$i],"?"))
{
$links=$linkinfo[$i]."&key=".$fromUsername;
}else
{
$links=$linkinfo[$i]."?key=".$fromUsername;
}
}else{
$links=$linkinfo[$i];
}
if(stristr($imageinfo[$i],$_SERVER['SERVER_NAME']))
{
$images=$imageinfo[$i];
}else
{
$images="http://".$_SERVER['SERVER_NAME'].__ROOT__.'/'.$imageinfo[$i];
}
$textTpl.= " <item>
<Title><![CDATA[".$titles[$i]."]]></Title>
<Description><![CDATA[".$titles[$i]."]]></Description>
<PicUrl><![CDATA[".$images."]]></PicUrl>
<Url><![CDATA[".$links."]]></Url>
</item>";
}
$textTpl.= "</Articles>
<FuncFlag>0</FuncFlag>
</xml>
";
$this->tuwen($textTpl,$fromUsername, $toUsername, $time,count($titles));
}
}else
{
}
}
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
}
上面就是封装的一个类 ,注释也写的很明白了。看不懂的在问,
3.下面我贴出我的微信菜单数据库和微信图文数据库
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for weixin_custom_menu
-- ----------------------------
DROP TABLE IF EXISTS `weixin_custom_menu`;
CREATE TABLE `weixin_custom_menu` (
`id` smallint(4) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`tags` varchar(50) NOT NULL,
`pid` smallint(4) unsigned NOT NULL,
`spid` varchar(50) NOT NULL,
`fcolor` varchar(10) NOT NULL,
`remark` text NOT NULL,
`add_time` int(10) NOT NULL,
`items` int(10) unsigned NOT NULL DEFAULT '0',
`likes` int(10) NOT NULL,
`type` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0:商品分类 1:标签分类',
`ordid` tinyint(3) unsigned NOT NULL DEFAULT '255',
`status` tinyint(1) NOT NULL,
`is_index` tinyint(1) NOT NULL DEFAULT '0',
`is_default` tinyint(1) unsigned NOT NULL DEFAULT '0',
`keyword` varchar(255) DEFAULT NULL COMMENT '关键词',
`key` varchar(255) DEFAULT NULL COMMENT 'key值',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Table structure for weixin_keyword
-- ----------------------------
DROP TABLE IF EXISTS `weixin_keyword`;
CREATE TABLE `weixin_keyword` (
`kid` int(11) unsigned NOT NULL AUTO_INCREMENT,
`kename` varchar(300) DEFAULT NULL,
`kecontent` varchar(500) DEFAULT NULL,
`type` tinyint(1) NOT NULL COMMENT '1:文本 2:多图文3:单图文',
`kyword` varchar(255) DEFAULT NULL,
`titles` varchar(1000) DEFAULT NULL,
`imageinfo` varchar(1000) DEFAULT NULL,
`linkinfo` varchar(1000) DEFAULT NULL,
`ismess` tinyint(1) DEFAULT NULL,
`isfollow` tinyint(1) DEFAULT NULL,
`iskey` tinyint(1) DEFAULT NULL,
`ispush` tinyint(1) DEFAULT NULL,
`content` text,
PRIMARY KEY (`kid`)
) ENGINE=MyISAM AUTO_INCREMENT=109 DEFAULT CHARSET=utf8;
上面的titles imageinfo linkinfo存储的时候要注意下前台页面传入后台是传的是array,然后序列化一下存入数据库,主要是图文的时候用到,标题,图片链接,点击图片跳转链接。
今天先到这,下次发群发推送的代码。