PHP實現接收郵件信息(我這里測試的騰訊企業郵件) , 其他的類型的沒有測,應該只要更換pop3地址 端口號就可以。
代碼如下(代碼參考網絡分享):
<?php //此處查看鏈接狀態 header("Content-type:text/html;charset=utf-8"); var_dump(fsockopen('pop.exmail.qq.com', 110, $error, $errorstr, 8)); // var_dump(fsockopen('pop.exmail.qq.com',110,$error,$errorstr,8)); print_r($error); echo '<br/>'; $host = "pop.exmail.qq.com"; //‘tls://’為ssl協議加密,端口走加密端口 $user = "xxx@xxx.com"; //郵箱 $pass = "xxxxxx"; //密碼 class Pop3 { var $hostname = ""; // POP主機名 var $port = 110; // 主機的POP3端口,一般是110號端口 var $timeout = 5; // 連接主機的最大超時時間 var $connection = 0; // 保存與主機的連接 var $state = "DISCONNECTED"; // 保存當前的狀態 var $debug = 0; // 做為標識,是否在調試狀態,是的話,輸出調試信息 var $err_str = ''; // 如果出錯,這里保存錯誤信息 var $err_no; //如果出錯,這里保存錯誤號碼 var $resp; // 臨時保存服務器的響應信息 var $apop; // 指示需要使用加密方式進行密碼驗證,一般服務器不需要 var $messages; // 郵件數 var $size; //各郵件的總大小 var $mail_list; // 一個數組,保存各個郵件的大小及其在郵件服務器上序號 var $head = array(); // 郵件頭的內容,數組 var $body = array(); // 郵件體的內容,數組; function pop3($server = "192.100.100.1", $port = 110, $time_out = 5) { $this->hostname = $server; $this->port = $port; $this->timeout = $time_out; return true; } function Open() { if ($this->hostname == "") { $this->err_str = "無效的主機名!!"; return false; } if ($this->debug) { echo "正在打開 {$this->hostname},{$this->port},{$err_no}, {$err_str}, {$this->timeout}<BR>"; } if (!($this->connection = @fsockopen($this->hostname, $this->port, $err_no, $err_str, $this->timeout))) { $this->err_str = "連接到POP3服務器失敗,錯誤信息:" . $err_str . "錯誤號:" . $err_no; return false; } else { $this->getresp(); if ($this->debug) { $this->outdebug($this->resp); } if (substr($this->resp, 0, 3) != "+OK") { $this->err_str = "服務器返回無效的信息:" . $this->resp . "請檢查POP服務器是否正確"; return false; } $this->state = "AUTHORIZATION"; return true; } } function getresp() { for ($this->resp = "";;) { if (feof($this->connection)) { return false; } $this->resp .= fgets($this->connection, 100); $length = strlen($this->resp); if ($length >= 2 && substr($this->resp, $length - 2, 2) == "\r\n") { $this->resp = strtok($this->resp, "\r\n"); return true; } } } //這個方法取得服務器端的返回信息並進行簡單的處理:去掉最后的回車換行符,將返回信息保存在resp這個內部變量中。這個方法在后面的多個操作中都將用到。另外,還有個小方法也在后面的多個操作中用到: function outdebug($message) { echo htmlspecialchars($message) . "<br>\n"; } //它的作用就是把調試信息$message顯示出來,並把一些特殊字符進行轉換以及在行尾加上<br>標簽,這樣是為了使其輸出的調試信息便於閱讀和分析。 //建立起與服務器的sock連接之后,就要給服務器發送相關的命令了(請參見上面的與服務器對話的過程)從上面對 POP對話的分析可以看到,每次都是發送一條命令,然后服務器給予一定的回應,如果命令的執行是對的,回應一般是以+OK開頭,后面是一些描述信息,所以,我們可以做一個通過發送命令的方法: function command($command, $return_lenth = 1, $return_code = '+') { if ($this->connection == 0) { $this->err_str = "沒有連接到任何服務器,請檢查網絡連接"; return false; } if ($this->debug) { $this->outdebug(">>> {$command}"); } if (!fputs($this->connection, "{$command}\r\n")) { $this->err_str = "無法發送命令" . $command; return false; } else { $this->getresp(); if ($this->debug) { $this->outdebug($this->resp); } if (substr($this->resp, 0, $return_lenth) != $return_code) { $this->err_str = $command . " 命令服務器返回無效:" . $this->resp; return false; } else { return true; } } } //這個方法可以接受三個參數: $command--> 發送給服務器的命令; $return_lenth,$return_code ,指定從服務器的返回中取多長的值做為命令返回的標識以及這個標識的正確值是什么。對於一般的pop操作來說,如果服務器的返回第一個字符為"+",則可以認為命令是正確執行了。也可以用前面提到過的三個字符"+OK"做為判斷的標識。 //下面介紹的幾個方法則可以按照前述收取信件的對話去理解,因為有關的內容已經在前面做了說明,因此下面的方法不做詳細的說明,請參考其中的注釋: function Login($user, $password) { if ($this->state != "AUTHORIZATION") { $this->err_str = "還沒有連接到服務器或狀態不對"; return false; } if (!$this->apop) { //服務器是否采用APOP用戶認證 if (!$this->command("USER {$user}", 3, "+OK")) { return false; } if (!$this->command("PASS {$password}", 3, "+OK")) { return false; } } else { if (!$this->command("APOP {$user} " . md5($this->greeting . $password), 3, "+OK")) { return false; } } $this->state = "TRANSACTION"; // 用戶認證通過,進入傳送模式 return true; } function stat() { if ($this->state != "TRANSACTION") { $this->err_str = "還沒有連接到服務器或沒有成功登錄"; return false; } if (!$this->command("STAT", 3, "+OK")) { return false; } else { $this->resp = strtok($this->resp, " "); $this->messages = strtok(" "); // 取得郵件總數 $this->size = strtok(" "); //取得總的字節大小 return true; } } function listmail($mess = null, $uni_id = null) { if ($this->state != "TRANSACTION") { $this->err_str = "還沒有連接到服務器或沒有成功登錄"; return false; } if ($uni_id) { $command = "UIDL "; } else { $command = "LIST "; } if ($mess) { $command .= $mess; } if (!$this->command($command, 3, "+OK")) { return false; } else { $i = 0; $this->mail_list = array(); $this->getresp(); while ($this->resp != ".") { $i++; if ($this->debug) { $this->outdebug($this->resp); } if ($uni_id) { $this->mail_list[$i][num] = strtok($this->resp, " "); $this->mail_list[$i][size] = strtok(" "); } else { $this->mail_list[$i]["num"] = intval(strtok($this->resp, " ")); $this->mail_list[$i]["size"] = intval(strtok(" ")); } $this->getresp(); } return true; } } function getmail($num = 1, $line = -1) { if ($this->state != "TRANSACTION") { $this->err_str = "不能收取信件,還沒有連接到服務器或沒有成功登錄"; return false; } if ($line < 0) { $command = "RETR {$num}"; } else { $command = "TOP {$num} {$line}"; } if (!$this->command("{$command}", 3, "+OK")) { return false; } else { $this->getresp(); $is_head = true; while ($this->resp != ".") { // . 號是郵件結束的標識 if ($this->debug) { $this->outdebug($this->resp); } if (substr($this->resp, 0, 1) == ".") { $this->resp = substr($this->resp, 1, strlen($this->resp) - 1); } if (trim($this->resp) == "") { // 郵件頭與正文部分的是一個空行 $is_head = false; } if ($is_head) { $this->head[] = $this->resp; } else { $this->body[] = $this->resp; } $this->getresp(); } return true; } } // end function function dele($num) { if ($this->state != "TRANSACTION") { $this->err_str = "不能刪除遠程信件,還沒有連接到服務器或沒有成功登錄"; return false; } if (!$num) { $this->err_str = "刪除的參數不對"; return false; } if ($this->command("DELE {$num} ", 3, "+OK")) { return true; } else { return false; } } //通過以上幾個方法,我們已經可以實現郵件的查看、收取、刪除的操作,不過別忘了最后要退出,並關閉與服務器的連接,調用下面的這個方法: function Close() { if ($this->connection != 0) { if ($this->state == "TRANSACTION") { $this->command("QUIT", 3, "+OK"); } fclose($this->connection); $this->connection = 0; $this->state = "DISCONNECTED"; } } } //參數1:為鏈接地址,參數2:為端口號,參數3為過載時間 $rec = new pop3($host, 110, 2); if (!$rec->open()) { die($rec->err_str); } echo "open "; if (!$rec->login($user, $pass)) { die($rec->err_str); } echo "login"; if (!$rec->stat()) { die($rec->err_str); } echo "共有" . $rec->messages . "封信件,共" . $rec->size . "字節大小<br>"; if ($rec->messages > 0) { if (!$rec->listmail()) { die($rec->err_str); } // echo "有以下信件:<br>"; // for ($i=1;$i<=count($rec->mail_list);$i++) // { // echo "信件".$rec->mail_list[$i]['num']."大小:".$rec->mail_list[$i]['size']."<BR>"; // } $rec->getmail(count($rec->mail_list)); // echo "郵件頭的內容:<br>"; // for ($i=0;$i<count($rec->head);$i++) // echo htmlspecialchars($rec->head[$i])."<br>\n"; echo "郵件正文 :<BR>"; for ($i = 0; $i < count($rec->body); $i++) { //如果加密返回 echo htmlspecialchars(quoted_printable_decode(base64_decode($rec->body[$i]))) . "<br>\n"; //如果內容明文直接輸出 // echo htmlspecialchars($rec->body[$i])."<br>\n"; } } $rec->close();
