imapChajian.php 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <?php
  2. /**
  3. * imap 收邮件扩展
  4. imap_search 使用返回Id
  5. http://php.net/manual/en/function.imap-search.php
  6. ALL 返回所有合乎标准的信件
  7. ANSWERED 信件有配置 \\ANSWERED 标志者
  8. BCC "字符串" Bcc 栏中有指定 "字符串" 的信件
  9. BEFORE "日期" 指定 "日期" 以前的信件
  10. BODY "字符串" 内文字段中有指定 "字符串" 的信件
  11. CC "字符串" Cc 栏中有指定 "字符串" 的信件
  12. DELETED 合乎已删除的信件
  13. FLAGGED 信件有配置 \\FLAGGED 标志者
  14. FROM "字符串" From 栏中有指定 "字符串" 的信件
  15. KEYWORD "字符串" 关键字为指定 "字符串" 者
  16. NEW 新的信件
  17. OLD 旧的信件
  18. ON "日期" 指定 "日期" 的信件
  19. RECENT 信件有配置 \\RECENT 标志者
  20. SEEN 信件有配置 \\SEEN 标志者
  21. SINCE "日期" 指定 "日期" 之后的信件
  22. SUBJECT "字符串" Subject 栏中有指定 "字符串" 的信件
  23. TEXT "字符串" Text 栏中有指定 "字符串" 的信件
  24. TO "字符串" To 栏中有指定 "字符串" 的信件
  25. UNANSWERED 未回应的信件
  26. UNDELETED 未删除的信件
  27. UNFLAGGED 未配置标志的信件
  28. UNKEYWORD "字符串" 未配置关键 "字符串" 的信件
  29. UNSEEN 未读取的信件
  30. */
  31. class imapChajian extends Chajian
  32. {
  33. private $supportbool = true,$marubox,$struck_tearr;
  34. protected function initChajian()
  35. {
  36. $this->supportbool = $this->isimap();
  37. $this->marubox = false;
  38. }
  39. public function isimap()
  40. {
  41. return function_exists('imap_open');
  42. }
  43. /**
  44. * 读取某日期后的邮件
  45. * @params $link 服务器
  46. * @params $user 邮箱
  47. * @params $pass 邮箱密码
  48. * @params $time 时间戳,默认7天前的
  49. */
  50. public function receemail($link, $user, $pass, $time=0)
  51. {
  52. if(isempt($link))return '未设置收邮件imap服务器';
  53. if(isempt($user))return '用户未设置邮箱';
  54. if(isempt($pass))return '邮箱['.$user.']未设置密码';
  55. if(!$this->supportbool)return '系统未开启imap收邮件扩展';
  56. $this->marubox = @imap_open($link,$user,$pass);
  57. $this->struck_tearr = array();
  58. if(!$this->marubox)return '不能连接到['.$link.']可能帐号密码有错';
  59. if($time == 0)$time = time() - 7*24*3600;
  60. $ondt = date('j M Y', $time);
  61. $searcharr = imap_search($this->marubox, 'SINCE "'.$ondt.'"');//指定日期之后
  62. $rows = array();
  63. //return $searcharr;
  64. if($searcharr)foreach($searcharr as $k=>$i){
  65. $headers = $this->getheader($i);
  66. $body = $this->getBody($i);
  67. $headers['body'] = $body;
  68. $headers['num'] = $i;
  69. $headers['attach'] = $this->getattach($i);
  70. $rows[] = $headers;
  71. }
  72. imap_close($this->marubox, CL_EXPUNGE);
  73. return $rows;
  74. $totalrows = imap_num_msg($this->marubox); //取得信件数
  75. $rows = array();
  76. for ($i=1;$i<=$totalrows;$i++){
  77. $headers = $this->getheader($i); //获取某信件的标头信息
  78. $body = $this->getBody($i); //获取信件正文
  79. $headers['body'] = $body;
  80. $headers['num'] = $i;
  81. $headers['attach'] = $this->getattach($i);
  82. $rows[] = $headers;
  83. }
  84. imap_close($this->marubox, CL_EXPUNGE);
  85. return $rows;
  86. }
  87. /**
  88. * 下载附件
  89. */
  90. public function downattach($link, $user, $pass, $num, $key)
  91. {
  92. }
  93. private function getfetchstructure($i)
  94. {
  95. if(!isset($this->struck_tearr[$i])){
  96. $struck = imap_fetchstructure($this->marubox,$i);
  97. }else{
  98. $struck = $this->struck_tearr[$i];
  99. }
  100. return $struck;
  101. }
  102. /**
  103. * 获取附件
  104. */
  105. private function getattach($i)
  106. {
  107. $arr = array();
  108. $struck = $this->getfetchstructure($i);
  109. if($struck && isset($struck->parts))foreach($struck->parts as $key=>$val){
  110. if($val->subtype=='OCTET-STREAM'){
  111. if(isset($val->dparameters[0]))$arr[] = array(
  112. 'filename' => $this->_imap_utf8($val->dparameters[0]->value),
  113. 'filesize' => $val->bytes,
  114. 'encoding' => $val->encoding,
  115. 'filekey' => $key,
  116. 'attachcont' => $this->getattachcont($i, $key, $val->encoding) //获取附件内容
  117. );
  118. }
  119. }
  120. return $arr;
  121. }
  122. /**
  123. * 附件内容读取,需要额外读取
  124. */
  125. public function getattachcont($i, $key, $encoding)
  126. {
  127. $message = imap_fetchbody($this->marubox, $i, $key + 1);
  128. switch ($encoding) {
  129. case 0:
  130. $message = imap_8bit($message);
  131. break;
  132. case 1:
  133. $message = imap_8bit($message);
  134. break;
  135. case 2:
  136. $message = imap_binary($message);
  137. break;
  138. case 3:
  139. $message = imap_base64($message);
  140. break;
  141. case 4:
  142. $message = quoted_printable_decode($message);
  143. break;
  144. case 5:
  145. $message = $message;
  146. break;
  147. }
  148. return $message;
  149. }
  150. private function getkevel($st, $kdy, $dev='')
  151. {
  152. return objvalue($st, $kdy, $dev);
  153. }
  154. /**
  155. * 获取某信件的标头信息
  156. */
  157. private function getheader($i)
  158. {
  159. $headers = imap_header($this->marubox, $i);
  160. $arr['subject'] = $this->_imap_utf8($this->getkevel($headers,'subject'));//标题
  161. $arr['message_id'] = $this->getkevel($headers,'message_id');//邮件ID
  162. $arr['size'] = $this->getkevel($headers,'Size','0'); //邮件大小
  163. $arr['date'] = date('Y-m-d H:i:s', strtotime($this->getkevel($headers,'date')));
  164. $arr['to'] = array();
  165. $arr['from'] = array();
  166. //发给
  167. if(isset($headers->to)){
  168. $arr['to'] = $headers->to;
  169. foreach($arr['to'] as $k=>$rs){
  170. $arr['to'][$k]->personal = $this->_imap_utf8($this->getkevel($rs, 'personal'));
  171. $arr['to'][$k]->email = ''.$rs->mailbox.'@'.$rs->host.'';
  172. }
  173. }
  174. $arr['toemail'] = $this->stremail($arr['to']);
  175. //发件人
  176. if(isset($headers->from)){
  177. $arr['from'] = $headers->from;
  178. foreach($arr['from'] as $k=>$rs){
  179. $arr['from'][$k]->personal = $this->_imap_utf8($this->getkevel($rs, 'personal'));
  180. $arr['from'][$k]->email = ''.$rs->mailbox.'@'.$rs->host.'';
  181. }
  182. }
  183. $arr['fromemail'] = $this->stremail($arr['from']);
  184. //回复的邮件
  185. if(isset($headers->reply_to)){
  186. $arr['reply_to'] = $headers->reply_to;
  187. foreach($arr['reply_to'] as $k=>$rs){
  188. $arr['reply_to'][$k]->personal = $this->_imap_utf8($this->getkevel($rs, 'personal'));
  189. $arr['reply_to'][$k]->email = ''.$rs->mailbox.'@'.$rs->host.'';
  190. }
  191. $arr['reply_toemail'] = $this->stremail($arr['reply_to']);
  192. }else{
  193. $arr['reply_toemail'] = $arr['fromemail'];
  194. }
  195. //抄送
  196. $arr['cc'] = array();
  197. if(isset($headers->cc)){
  198. $arr['cc'] = $headers->cc;
  199. foreach($arr['cc'] as $k=>$rs){
  200. $arr['cc'][$k]->personal = $this->_imap_utf8($this->getkevel($rs, 'personal'));
  201. $arr['cc'][$k]->email = ''.$rs->mailbox.'@'.$rs->host.'';
  202. }
  203. }
  204. $arr['ccemail'] = $this->stremail($arr['cc']);
  205. $arr['headers'] = $headers;
  206. return $arr;
  207. }
  208. private function stremail($arr)
  209. {
  210. $str = '';
  211. if(is_array($arr))foreach($arr as $k=>$rs){
  212. $str.=','.$rs->personal.'('.$rs->mailbox.'@'.$rs->host.')';
  213. }
  214. if($str!='')$str = substr($str, 1);
  215. return $str;
  216. }
  217. private function _imap_utf8($text) {
  218. $text = iconv_mime_decode($text,0, 'UTF-8');
  219. return $text;
  220. }
  221. private function _iconv_utf8($text) {
  222. $encode = mb_detect_encoding($text, array('ASCII','UTF-8','GB2312','GBK','BIG5'));
  223. if($encode != 'UTF-8'){
  224. return @iconv($encode, 'utf-8', $text);
  225. }else{
  226. return $text;
  227. }
  228. @$s1 = iconv('gbk', 'utf-8', $text);
  229. $s0 = iconv('utf-8', 'gbk', $s1);
  230. if ($s0 == $text) {
  231. return $s1;
  232. } else {
  233. return $text;
  234. }
  235. }
  236. function get_mime_type(&$structure) { //Get Mime type Internal Private Use
  237. $primary_mime_type = array("TEXT", "MULTIPART", "MESSAGE", "APPLICATION", "AUDIO", "IMAGE", "VIDEO", "OTHER");
  238. if ($structure->subtype) {
  239. return $primary_mime_type[(int) $structure->type] . '/' . $structure->subtype;
  240. }
  241. return "TEXT/PLAIN";
  242. }
  243. private function get_part($stream, $msg_number, $mime_type, $structure = false, $part_number = false) { //Get Part Of Message Internal Private Use
  244. if (!$structure) {
  245. $structure = $this->getfetchstructure($msg_number);;
  246. }
  247. if ($structure) {
  248. if ($mime_type == $this->get_mime_type($structure)) {
  249. if (!$part_number) {
  250. $part_number = "1";
  251. }
  252. $text = imap_fetchbody($stream, $msg_number, $part_number);
  253. if ($structure->encoding == 3) {
  254. return imap_base64($text);
  255. } else if ($structure->encoding == 4) {
  256. return imap_qprint($text);
  257. } else {
  258. return $text;
  259. }
  260. }
  261. if ($structure->type == 1) /* multipart */ {
  262. while (list($index, $sub_structure) = each($structure->parts)) {
  263. $prefix = '';
  264. if ($part_number) {
  265. $prefix = $part_number . '.';
  266. }
  267. $data = $this->get_part($stream, $msg_number, $mime_type, $sub_structure, $prefix . ($index + 1));
  268. if ($data) {
  269. return $data;
  270. }
  271. }
  272. }
  273. }
  274. return false;
  275. }
  276. /**
  277. * 获取邮件内容
  278. */
  279. private function getBody($mid) {
  280. $body = $this->get_part($this->marubox, $mid, "TEXT/HTML");
  281. if ($body == "") {
  282. $body = $this->get_part($this->marubox, $mid, "TEXT/PLAIN");
  283. }
  284. if ($body == "") {
  285. return "";
  286. }
  287. return $this->_iconv_utf8($body);
  288. }
  289. }
粤ICP备19079148号