做了一个加速器账号出租的项目,按小时收费往外租加速器账号,时间到了之后,系统自动修改加速器的密码
修改密码需要进入绑定的邮箱,点击修改密码的链接,然后在新页面中提交新密码,这一切都需要后台自动完成
将过期的账号放到一个消息队列中,然后一个一个修改,修改出错的标记上,提醒人工修改
下面通过后台管理页面每20秒左右访问这个接口,从消息队列中读取待修改的账
public function change_pwd_GET(){
//取出一个未处理的号 $where_2['state ='] = 0; //未处理 $res = $this->sql('other.jiasu_change_pwd')->select()->where($where_2)->limit(1)->query(); if(count($res) == 0){ out('{"rt":200,"msg":"没有到期账号"}'); return; }
//找回密码的界面,填入自己的邮箱 $rt = curl_do('http://www.XXXXX.com/user.php',['email' => $res[0]['email'],'act' => 'send_pwd_email'],'POST',['header' => [USER_AGENT]]); //邮件发送出错 if(!strpos($rt[1],'code":0')){ //将队列中的状态改为1,表明自动修改失败 out('{"rt":300,"msg":"邮件发送出错"}'); return; } sleep(4);//等待邮件发送成功 //读取邮件中的信息,并从邮件中提取出添加新密码的链接 $href = jsHrefGet($res[0]['email'],$res[0]['emailpwd']); if($href == false){ out('{"rt":300,"msg":"邮件读取失败"}'); return; } if($href !== false){ $rt = curl_do($href,'','GET',['need_header' => true,'header' => [USER_AGENT]]); if($rt[0] === 302){ preg_match('/Location: (.+)\r\n/U',$rt[1],$Location); if(isset($Location[1])){ $rt = curl_do($Location[1],'','GET',['need_header' => true,'header' => [USER_AGENT]]); if($rt[0] === 200){ if(strpos($rt[1],'无效链接') === false){ preg_match('/name="code" value="(.+)"/U',$rt[1],$code); if(isset($code[1])){ $cookies = curl_cookie($rt[1]); $new_password = rand_pwdd(); $rt = curl_do('http://www.XXXXX.com/user.php','new_password='.$new_password.'&target=&confirm_password='.$new_password.'&act=act_edit_password&uid=&code='.$code[1].'&Submit=%E6%8F%90%E4%BA%A4','POST',['cookie' => $cookies,'header' => [USER_AGENT]]); if($rt[0] === 200 && strpos($rt[1],'您的密码已修改成功,请牢记!') !== false){ // todo... 修改数据库中的密码和重新上架出租 out('{"rt":0,"msg":"Success"}'); }else{ //将队列中的状态改为3,表明自动修改失败 out('{"rt":101,"msg":"修改密码出错"}'); return; } } }else{ //将队列中的状态改为3,表明自动修改失败 out('{"rt":101,"msg":"链接失效"}'); return; } } } } } die(); }
用到的两个函数
function jsHrefGet($mail,$pwd){ if(strpos($mail,'@sina.com') !== false){ $imap = imap_open('{imap.sina.cn:993/ssl}INBOX',$mail,$pwd); }else{ $imap = imap_open('{imap.qq.com:993/ssl}INBOX',$mail,$pwd); } $mail_num = imap_num_msg($imap); for($i = $mail_num;$i > 0;-- $i){ $header = imap_header($imap,$i); if(isset($header->to[0])){ $from = $header->from[0]->mailbox.'@'.$header->from[0]->host; $to = $header->to[0]->mailbox.'@'.$header->to[0]->host; $body = imap_qprint(imap_fetchbody($imap,$i,1)); $body = strtr($body,[' ' => '',' ' => '',"\r\n" => '',"\n" => '']); //print($body); preg_match('/新密码重置操作!<ahref="(.+)">http:\/\/www.XXXXXX.com\/\//U',$body,$href); //preg_match('/新密码重置操作!<ahref="(.+)" /U',$body,$href); //var_dump($href); if(isset($href[1])){ if($from === 'account@service.htjsq.com' && $to == $mail){ return $href[1]; } } } } return false; } function rand_pwdd(){ $str = 'abcdefghijkmnpqrstuvwxyz23456789'; $strLen = strlen($str) - 1; $randStr = ''; for($i = 0;$i < 8;++ $i){ $randStr .= $str[mt_rand(0,$strLen)]; } return $randStr; }
每个项目的页面都是不一样的,正则的写法也不一样,主要体会读取邮件(需要开通IMAP),curl操作的学习
curl_do的自动封装
/** * curl_do **/ function curl_do($url,$data = '',$method = 'GET',$param = []){ // 通过curl请求一个url,data为k=v&k1=v1的格式(数组时自动整理)或post一个xml数据 // 如果使用证书则在$cert参数传入包含证书cert.pem和私钥key.pem的文件夹路径 if(!isset($param['cookie'])){ $param['cookie'] = false; } if(!isset($param['header'])){ $param['header'] = false; } if(!isset($param['timeout'])){ $param['timeout'] = 10; } if(!isset($param['need_header'])){ $param['need_header'] = false; } if(!isset($param['cert'])){ $param['cert'] = false; } $ch = curl_init(); switch($method){ case 'GET': if(is_array($data)){ $data_str = ''; if(count($data) !== 0){ foreach($data as $k => $v){ $data_str .= '&'.$k.'='.urlencode($v); } $data_str = substr($data_str,1); } }else{ $data_str = &$data; } curl_setopt($ch,CURLOPT_URL,$url.($data_str === '' ? '' : '?'.$data_str)); break; case 'POST': curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_POST,true); curl_setopt($ch,CURLOPT_POSTFIELDS,$data); break; case 'PUT': case 'DELETE': curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_CUSTOMREQUEST,$method); curl_setopt($ch,CURLOPT_POSTFIELDS,$data); break; } if($param['cert'] !== false){ // 如果使用证书 // 证书和证书路径 curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT,$param['cert'].'cert.pem'); // 私钥和私钥路径 curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY,$param['cert'].'key.pem'); } if(substr($url,0,5) === 'https'){ // 如果是ssl安全请求 curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); } // 如果设置cookie if($param['cookie'] !== false){ if(is_array($param['cookie'])){ $cookie_str = ''; if(count($param['cookie']) !== 0){ foreach($param['cookie'] as $k => $v){ $cookie_str .= '; '.$k.'='.$v; } $cookie_str = substr($cookie_str,2); } $param['cookie'] = $cookie_str; } curl_setopt($ch,CURLOPT_COOKIE,$param['cookie']); } // 如果设置header if($param['header'] !== false){ curl_setopt($ch,CURLOPT_HTTPHEADER,$param['header']); } curl_setopt($ch,CURLOPT_HEADER,$param['need_header']); // 将头文件的信息作为数据流输出 curl_setopt($ch,CURLOPT_TIMEOUT,$param['timeout']); curl_setopt($ch,CURLOPT_ENCODING,''); curl_setopt($ch,CURLOPT_RETURNTRANSFER,true); // 要求结果为字符串且输出到屏幕 $rt = []; $rt[1] = curl_exec($ch); $rt[0] = curl_getinfo($ch,CURLINFO_HTTP_CODE); $rt[2] = $url; $rt[3] = $method; $rt[4] = $data; $rt[5] = curl_errno($ch); curl_close($ch); return $rt; }