php实现个人微信给自己好友发送消息

时间:2024-02-22 18:00:35

<?php
$wx = new wx();
if (!empty($_GET[\'cmd\']) && $_GET[\'cmd\'] == \'index\') {
//重新扫描登陆时,清空缓存
session_start();
unset($_SESSION);
session_destroy();
$uuid = $wx->get_uuid();
$erweima = $wx->qrcode($uuid);
echo($erweima);//显示二维码
echo "<a href=\'wx2.php?cmd=login&uuid=" . $uuid . "\'>扫描后,点击登陆确认</a>(备注:扫描后点击登陆按钮" . $uuid . ")";
}

if (!empty($_GET[\'cmd\']) && $_GET[\'cmd\'] == \'login\' && !empty($_GET[\'uuid\'])) {
//echo $_GET[\'uuid\'];die;
$loginInfo = $wx->login($_GET[\'uuid\']);
if ($loginInfo[\'code\'] == 200) {
//获取登录成功回调
$callback = $wx->get_uri($_GET[\'uuid\']);
//获取post数据
$post = $wx->post_self($callback);
//初始化数据json格式
$initInfo = $wx->wxinit($post);

//获取MsgId,参数post,初始化数据initInfo
//$msgInfo = $wx->wxstatusnotify($post,$initInfo,$callback[\'post_url_header\']);
//获取联系人
$contactInfo = $wx->webwxgetcontact($post, $callback[\'post_url_header\']);

//查询的数据放入缓存
session_start();
$_SESSION[\'callback_post_url_header\'] = $callback[\'post_url_header\'];
$_SESSION[\'post\'] = $post;
$_SESSION[\'initInfo\'] = $initInfo;
$_SESSION[\'contactInfo\'] = $contactInfo;
//print_r($_SESSION[\'callback_post_url_header\']);die;
header("Location: wx2.php?cmd=send");
exit;
}
//print_r($loginInfo);
print_r(\'登陆失败\');
}
if (!empty($_GET[\'cmd\']) && $_GET[\'cmd\'] == \'send\') {
//header("Content-Type: text/html; charset=UTF-8");
if (!empty($_POST[\'sendText\'])) {
session_start();

$callback = $_SESSION[\'callback_post_url_header\'];
$post = $_SESSION[\'post\'];
$initInfo = $_SESSION[\'initInfo\'];
$contactInfo = $_SESSION[\'contactInfo\'];
//json转数组
$contactArr = json_decode($contactInfo, true);
$contactName = anewarray($contactArr[\'MemberList\'], \'UserName\');
//$userName = $contactName[\'文件传输助手\'];//文件助手 :文件传输助手,好友:荳子麻麻
//发送信息
//接受消息
$sendText = $_POST[\'sendText\'];
$userName = $_POST[\'username\'];
//print_r($sendText);print_r($userName);die;
$word = urlencode($sendText);//中文先转码,最后提交的时候在urldecode(json_encode($data));
$to = $userName;
if (!empty($sendText)) {
$sendmsg = $wx->webwxsendmsg($post, $initInfo, $callback, $to, $word);
// $msg = $word . date("Y-m-d H:i:s") . "\r\n";
// file_put_contents("logs/log.log", $msg, FILE_APPEND);//记录日志
header("Location: wx2.php?cmd=send");
}
} else {
session_start();

$contactInfo = $_SESSION[\'contactInfo\'];
//json转数组
$contactArr = json_decode($contactInfo, true);
$contactName = anewarray($contactArr[\'MemberList\'], \'UserName\');

echo "<form action=\'wx2.php?cmd=send\' method=\'post\'>";
echo "<select name = \'username\'>";
foreach ($contactName as $k => $v) {
echo "<option value =" . $v . ">" . $k . "</option>";
}
echo "</select>";
echo "消息: <input type=\'text\' name=\'sendText\' id=\'sendText\'>";
echo "<input type=\'submit\' value=\'发送\'>";
echo "</form>";
}


}

class Wx
{

function getMillisecond()
{
list($t1, $t2) = explode(\' \', microtime());
return $t2 . ceil(($t1 * 1000));
}

private $appid = \'wx782c26e4c19acffb\';

/**
* 获取唯一的uuid用于生成二维码
* @return $uuid
*/
public function get_uuid()
{
$url = \'https://login.weixin.qq.com/jslogin\';
$url .= \'?appid=\' . $this->appid;
$url .= \'&fun=new\';
$url .= \'&lang=zh_CN\';
$url .= \'&_=\' . time();

$content = $this->curlPost($url);
//也可以使用正则匹配
$content = explode(\';\', $content);

$content_uuid = explode(\'"\', $content[1]);

$uuid = $content_uuid[1];
$this->uuid = $uuid;
return $uuid;
}

/**
* 生成二维码
* @param $uuid
* @return img
*/
public function qrcode($uuid)
{
$url = \'https://login.weixin.qq.com/qrcode/\' . $uuid . \'?t=webwx\';
$img = "<img class=\'img\' src=" . $url . "/>";
return $img;
}

/**
* 扫描登录
* @param $uuid
* @param string $icon
* @return array code 408:未扫描;201:扫描未登录;200:登录成功; icon:用户头像
*/
public function login($uuid, $icon = \'true\')
{
//$url = \'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=\' . $icon . \'&r=\' . ~time() . \'&uuid=\' . $uuid . \'&tip=0&_=\' . getMillisecond();
$url = \'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?loginicon=\' . $icon . \'&r=\' . ~time() . \'&uuid=\' . $uuid . \'&tip=0&_=\' . time();
$content = $this->curlPost($url);
preg_match(\'/\d+/\', $content, $match);
$code = $match[0];
preg_match(\'/([\\'"])([^\\'"\.]*?)\1/\', $content, $icon);

$user_icon = !empty($icon) ? $icon[2] : array();
if ($user_icon) {
$data = array(
\'code\' => $code,
\'icon\' => $user_icon,
);
} else {
$data[\'code\'] = $code;
}
//echo json_encode($data);//改之前
return $data;
}

/**
* 登录成功回调
* @param $uuid
* @return array $callback
*/
public function get_uri($uuid)
{
$url = \'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid=\' . $uuid . \'&tip=0&_=e\' . time();
$content = $this->curlPost($url);
$content = explode(\';\', $content);
$content_uri = explode(\'"\', $content[1]);
$uri = $content_uri[1];

preg_match("~^https:?(//([^/?#]*))?~", $uri, $match);
$https_header = $match[0];
$_SESSION[\'https_header\'] = $https_header;//补这一句
$post_url_header = $https_header . "/cgi-bin/mmwebwx-bin";

$new_uri = explode(\'scan\', $uri);
$uri = $new_uri[0] . \'fun=new&scan=\' . time();
$getXML = $this->curlPost($uri);

$XML = simplexml_load_string($getXML);

$callback = array(
\'post_url_header\' => $post_url_header,
\'Ret\' => (array)$XML,
);
return $callback;
}

/**
* 获取post数据
* @param array $callback
* @return object $post
*/
public function post_self($callback)
{
$post = new stdClass();
$Ret = $callback[\'Ret\'];
$status = $Ret[\'ret\'];
if ($status == \'1203\') {
$this->error(\'未知错误,请2小时后重试\');
}
if ($status == \'0\') {
$post->BaseRequest = array(
\'Uin\' => $Ret[\'wxuin\'],
\'Sid\' => $Ret[\'wxsid\'],
\'Skey\' => $Ret[\'skey\'],
\'DeviceID\' => \'e\' . rand(10000000, 99999999) . rand(1000000, 9999999),
);

$post->skey = $Ret[\'skey\'];

$post->pass_ticket = $Ret[\'pass_ticket\'];

$post->sid = $Ret[\'wxsid\'];

$post->uin = $Ret[\'wxuin\'];

return $post;
}
}

/**
* 初始化
* @param $post
* @return json $json
*/
public function wxinit($post)
{

$url = $_SESSION[\'https_header\'] . \'/cgi-bin/mmwebwx-bin/webwxinit?pass_ticket=\' . $post->pass_ticket . \'&skey=\' . $post->skey . \'&r=\' . time();

$post = array(
\'BaseRequest\' => $post->BaseRequest,
);
$json = $this->curlPost($url, $post);

return $json;
}

/**
* 获取MsgId
* @param $post
* @param $json
* @param $post_url_header
* @return array $data
*/
public function wxstatusnotify($post, $json, $post_url_header)
{
$init = json_decode($json, true);

$User = $init[\'User\'];
$url = $post_url_header . \'/webwxstatusnotify?lang=zh_CN&pass_ticket=\' . $post->pass_ticket;

$params = array(
\'BaseRequest\' => $post->BaseRequest,
"Code" => 3,
"FromUserName" => $User[\'UserName\'],
"ToUserName" => $User[\'UserName\'],
"ClientMsgId" => time()
);

$data = $this->curlPost($url, $params);

$data = json_decode($data, true);

return $data;
}

/**
* 获取联系人
* @param $post
* @param $post_url_header
* @return array $data
*/
public function webwxgetcontact($post, $post_url_header)
{

$url = $post_url_header . \'/webwxgetcontact?pass_ticket=\' . $post->pass_ticket . \'&seq=0&skey=\' . $post->skey . \'&r=\' . time();

$params[\'BaseRequest\'] = $post->BaseRequest;

$data = $this->curlPost($url, $params);

return $data;
}

/**
* 获取当前活跃群信息
* @param $post
* @param $post_url_header
* @param $group_list 从获取联系人和初始化中获取
* @return array $data
*/
public function webwxbatchgetcontact($post, $post_url_header, $group_list)
{

$url = $post_url_header . \'/webwxbatchgetcontact?type=ex&lang=zh_CN&r=\' . time() . \'&pass_ticket=\' . $post->pass_ticket;

$params[\'BaseRequest\'] = $post->BaseRequest;

$params[\'Count\'] = count($group_list);

foreach ($group_list as $key => $value) {
if ($value[MemberCount] == 0) {
$params[\'List\'][] = array(
\'UserName\' => $value[\'UserName\'],
\'ChatRoomId\' => "",
);
}
$params[\'List\'][] = array(
\'UserName\' => $value[\'UserName\'],
\'EncryChatRoomId\' => "",
);

}

$data = $this->curlPost($url, $params);

$data = json_decode($data, true);

return $data;
}

/**
* 心跳检测 0正常;1101失败/登出;2新消息;7不要耍手机了我都收不到消息了;
* @param $post
* @param $SyncKey 初始化方法中获取
* @return array $status
*/
public function synccheck($post, $SyncKey)
{
if (!$SyncKey[\'List\']) {
$SyncKey = $_SESSION[\'json\'][\'SyncKey\'];
}
foreach ($SyncKey[\'List\'] as $key => $value) {
if ($key == 1) {
$SyncKey_value = $value[\'Key\'] . \'_\' . $value[\'Val\'];
} else {
$SyncKey_value .= \'|\' . $value[\'Key\'] . \'_\' . $value[\'Val\'];
}

}

$header = array(
\'0\' => \'https://webpush.wx2.qq.com\',
\'1\' => \'https://webpush.wx.qq.com\',
);

foreach ($header as $key => $value) {

$url = $value . "/cgi-bin/mmwebwx-bin/synccheck?r=" . getMillisecond() . "&skey=" . urlencode($post->skey) . "&sid=" . $post->sid . "&deviceid=" . $post->BaseRequest[\'DeviceID\'] . "&uin=" . $post->uin . "&synckey=" . urlencode($SyncKey_value) . "&_=" . getMillisecond();

$data[] = $this->curlPost($url);
}

foreach ($data as $k => $val) {

$rule = \'/window.synccheck={retcode:"(\d+)",selector:"(\d+)"}/\';

preg_match($rule, $data[$k], $match);

if ($match[1] == \'0\') {
$retcode = $match[1];
$selector = $match[2];
}
}

$status = array(
\'ret\' => $retcode,
\'sel\' => $selector,
);

return $status;
}

/**
* 获取最新消息
* @param $post
* @param $post_url_header
* @param $SyncKey
* @return array $data
*/
public function webwxsync($post, $post_url_header, $SyncKey)
{
$url = $post_url_header . \'/webwxsync?sid=\' . $post->sid . \'&skey=\' . $post->skey . \'&pass_ticket=\' . $post->pass_ticket;

$params = array(
\'BaseRequest\' => $post->BaseRequest,
\'SyncKey\' => $SyncKey,
\'rr\' => ~time(),
);
$data = $this->curlPost($url, $params);

return $data;
}


/**
* 发送消息
* @param $post
* @param $post_url_header
* @param $to 发送人
* @param $word
* @return array $data
*/
public function webwxsendmsg($post, $json, $post_url_header, $to, $word)
{

//header("Content-Type: application/json; charset=UTF-8");
//header("Content-Type: application/x-www-form-urlencoded; charset=UTF-8");
$url = $post_url_header . \'/webwxsendmsg?pass_ticket=\' . $post->pass_ticket;

//$clientMsgId = getMillisecond() * 1000 + rand(1000, 9999);//原方法
$clientMsgId = time() * 1000 + rand(1000, 9999);//原方法
$init = json_decode($json, true);
$User = $init[\'User\'];
$params = array(
\'BaseRequest\' => $post->BaseRequest,
\'Msg\' => array(
"Type" => 1,
"Content" => $word,
"FromUserName" => $User[\'UserName\'],
"ToUserName" => $to,
"LocalID" => $clientMsgId,
"ClientMsgId" => $clientMsgId
),
\'Scene\' => 0,
);
$data = $this->sendCurlPost($url, $params, 1);

return $data;
}

/**
*退出登录
* @param $post
* @param $post_url_header
* @return bool
*/
public function wxloginout($post, $post_url_header)
{
$url = $post_url_header . \'/webwxlogout?redirect=1&type=1&skey=\' . urlencode($post->skey);
$param = array(
\'sid\' => $post->sid,
\'uin\' => $post->uin,
);
$this->curlPost($url, $param);

return true;
}


public function curlPost($url, $data = \'\', $is_gbk = false, $timeout = 30, $CA = false)
{
$cacert = getcwd() . \'/cacert.pem\'; //CA根证书

$SSL = substr($url, 0, 8) == "https://" ? true : false;

//$header = \'ContentType: application/json; charset=UTF-8\';
$header[] = \'ContentType: application/json;\';
$header[] = "charset:UTF-8";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout - 2);
if ($SSL && $CA) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 只信任CA颁布的证书
curl_setopt($ch, CURLOPT_CAINFO, $cacert); // CA根证书(用来验证的网站证书是否是CA颁布)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名,并且是否与提供的主机名匹配
} else if ($SSL && !$CA) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(\'Expect:\')); //避免data数据过长问题
if ($data) {
if ($is_gbk) {
$data = json_encode($data);

} else {
$data = json_encode($data);
}

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}

//curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); //data with URLEncode
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}

public function sendCurlPost($url, $data = \'\', $is_gbk = false, $timeout = 30, $CA = false)
{
$cacert = getcwd() . \'/cacert.pem\'; //CA根证书

$SSL = substr($url, 0, 8) == "https://" ? true : false;

//$header = \'ContentType: application/json; charset=UTF-8\';
$header[] = \'ContentType: application/json;\';
$header[] = "charset:UTF-8";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout - 2);
if ($SSL && $CA) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true); // 只信任CA颁布的证书
curl_setopt($ch, CURLOPT_CAINFO, $cacert); // CA根证书(用来验证的网站证书是否是CA颁布)
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名,并且是否与提供的主机名匹配
} else if ($SSL && !$CA) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 信任任何证书
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); // 检查证书中是否设置域名
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(\'Expect:\')); //避免data数据过长问题
if ($data) {
if ($is_gbk) {
$data = urldecode(json_encode($data));

} else {
$data = urldecode(json_encode($data));
}

curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
}

//curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); //data with URLEncode
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
}

 

 

function anewarray($array, $filed = \'UserName\', $keyName = \'NickName\')
{
$data = array();
if (!empty($array)) {
foreach ($array as $key => $val) {
if (!empty($val[$filed])) {
$data[$val[$keyName]] = $val[$filed];
}
}
$data = array_filter($data);
}

return $data;
}