成人在线亚洲_国产日韩视频一区二区三区_久久久国产精品_99国内精品久久久久久久

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

用PHP實(shí)現(xiàn)POP3郵件的收?。ǘ?/h1>
瀏覽:2日期:2023-12-28 10:15:43

用PHP實(shí)現(xiàn)POP3收取郵件的類

現(xiàn)在讓我們來(lái)用PHP實(shí)現(xiàn)一個(gè)通過(guò)POP3協(xié)議收取信件的類吧,這個(gè)類中所用到的一些sock操作的函數(shù),不另做特殊說(shuō)明,請(qǐng)參考php的有關(guān)資料。通過(guò)這個(gè)實(shí)例,相信你也會(huì)和我一樣,感覺到PHP中對(duì)于sock操作的靈活、方便和功能的強(qiáng)大。

首先,我們來(lái)說(shuō)明一下這個(gè)類中需要用到的一些內(nèi)部成員變量:(這些變量應(yīng)該都是對(duì)外封閉的,可是由于php對(duì)類的成員變量沒有private與publice之類的分別,只好就這么直接定義了。這是PHP的一個(gè)令人遺憾的地方。)

1.成員變量說(shuō)明

class pop3{

var $hostname=''; // POP主機(jī)名

var $port=110; // 主機(jī)的POP3端口,一般是110號(hào)端口

var $timeout=5;// 連接主機(jī)的最大超時(shí)時(shí)間 

var $connection=0; // 保存與主機(jī)的連接

var $state='DISCONNECTED'; // 保存當(dāng)前的狀態(tài) 

var $debug=0;// 做為標(biāo)識(shí),是否在調(diào)試狀態(tài),是的話,輸出調(diào)試信息

var $err_str='';// 如果出錯(cuò),這里保存錯(cuò)誤信息

var $err_no; //如果出錯(cuò),這里保存錯(cuò)誤號(hào)碼

var $resp; // 臨時(shí)保存服務(wù)器的響應(yīng)信息

var $apop; // 指示需要使用加密方式進(jìn)行密碼驗(yàn)證,一般服務(wù)器不需要

var $messages; // 郵件數(shù)

var $size; //各郵件的總大小

var $mail_list; // 一個(gè)數(shù)組,保存各個(gè)郵件的大小及其在郵件服務(wù)器上序號(hào)  

var $head=array(); // 郵件頭的內(nèi)容,數(shù)組

var $body=array(); // 郵件體的內(nèi)容,數(shù)組;

2.當(dāng)然,這其中的有些變量,僅通過(guò)這樣一個(gè)簡(jiǎn)單的說(shuō)明并不能完全了解如何使用,下面我就逐個(gè)來(lái)說(shuō)明這個(gè)類實(shí)現(xiàn)中的一些主要方法:Function pop3($server='192.100.100.1',$port=110,$time_out=5)

{$this->hostname=$server;

$this->port=$port;

$this->timeout=$time_out;

return true;}

熟悉面向?qū)ο缶幊痰呐笥岩豢淳蜁?huì)知道,這是這個(gè)類的構(gòu)造函數(shù),在初始化這個(gè)類時(shí),可以給出這幾個(gè)最基本的參數(shù):pop3服務(wù)器的地址,端口號(hào),及連接服務(wù)器時(shí)的最大超時(shí)時(shí)間。一般來(lái)說(shuō),只需要給出POP3服務(wù)器的地址就行了。

Function open(){if($this->hostname=='')

{$this->err_str='無(wú)效的主機(jī)名!!';

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='連接到POP服務(wù)器失敗,錯(cuò)誤信息:'.$err_str.'錯(cuò)誤號(hào):'.$err_no;

return false;

} else { $this->getresp();

if($this->debug)

$this->outdebug($this->resp);

if (substr($this->resp,0,3)!='+OK')

{$this->err_str='服務(wù)器返回?zé)o效的信息:'.$this->resp.'請(qǐng)檢查POP服務(wù)器是否正確';

return false; }

$this->state='AUTHORIZATION';

return true;

}

}

該方法不需要任何參數(shù)就可建立與POP3服務(wù)器的sock連接。該方法又用到了另一個(gè)類中的方法$this->getresp();下面是這個(gè)方法的聲明:

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)=='rn')

{

$this->resp=strtok($this->resp,'rn');

return true;

}}}

這個(gè)方法取得服務(wù)器端的返回信息并進(jìn)行簡(jiǎn)單的處理:去掉最后的回車換行符,將返回信息保存在resp這個(gè)內(nèi)部變量中。這個(gè)方法在后面的多個(gè)操作中都將用到。另外,還有個(gè)小方法也在后面的多個(gè)操作中用到:

Function outdebug($message){ echo htmlspecialchars($message).'<br>n';}

它的作用就是把調(diào)試信息$message顯示出來(lái),并把一些特殊字符進(jìn)行轉(zhuǎn)換以及在行尾加上<br>標(biāo)簽,這樣是為了使其輸出的調(diào)試信息便于閱讀和分析。

建立起與服務(wù)器的sock連接之后,就要給服務(wù)器發(fā)送相關(guān)的命令了(請(qǐng)參見上面的與服務(wù)器對(duì)話的過(guò)程)從上面對(duì) POP對(duì)話的分析可以看到,每次都是發(fā)送一條命令,然后服務(wù)器給予一定的回應(yīng),如果命令的執(zhí)行是對(duì)的,回應(yīng)一般是以+OK開頭,后面是一些描述信息,所以,我們可以做一個(gè)通過(guò)發(fā)送命令的方法:

Function command($command,$return_lenth=1,$return_code='+'){ if ($this->connection==0) { $this->err_str='沒有連接到任何服務(wù)器,請(qǐng)檢查網(wǎng)絡(luò)連接';

return false; }

if ($this->debug) $this->outdebug('>>> $command');

if (!fputs($this->connection,'$commandrn'))

{

$this->err_str='無(wú)法發(fā)送命令'.$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.' 命令服務(wù)器返回?zé)o效:'.$this->resp;

return false;

}

else

return true;

}}

這個(gè)方法可以接受三個(gè)參數(shù): $command--> 發(fā)送給服務(wù)器的命令; $return_lenth,$return_code ,指定從服務(wù)器的返回中取多長(zhǎng)的值做為命令返回的標(biāo)識(shí)以及這個(gè)標(biāo)識(shí)的正確值是什么。對(duì)于一般的pop操作來(lái)說(shuō),如果服務(wù)器的返回第一個(gè)字符為'+',則可以認(rèn)為命令是正確執(zhí)行了。也可以用前面提到過(guò)的三個(gè)字符'+OK'做為判斷的標(biāo)識(shí)。

下面介紹的幾個(gè)方法則可以按照前述收取信件的對(duì)話去理解,因?yàn)橛嘘P(guān)的內(nèi)容已經(jīng)在前面做了說(shuō)明,因此下面的方法不做詳細(xì)的說(shuō)明,請(qǐng)參考其中的注釋:

Function Login($user,$password) //發(fā)送用戶名及密碼,登錄到服務(wù)器{

if($this->state!='AUTHORIZATION') {

$this->err_str='還沒有連接到服務(wù)器或狀態(tài)不對(duì)';

return false; }

if (!$this->apop) //服務(wù)器是否采用APOP用戶認(rèn)證 {

if (!$this->command('USER $user',3,'+OK')) return false;

if (!$this->command('PASS $password',3,'+OK')) return false;

}

else

{

//echo $this->resp=strtok($this->resp,'rn');

if (!$this->command('APOP $user '.md5($this->greeting.$password),3,'+OK')) return false;

}

$this->state='TRANSACTION'; // 用戶認(rèn)證通過(guò),進(jìn)入傳送模式

return true;}

Function stat() // 對(duì)應(yīng)著stat命令,取得總的郵件數(shù)與總的大小{if($this->state!='TRANSACTION') {

$this->err_str='還沒有連接到服務(wù)器或沒有成功登錄';

return false; }

if (!$this->command('STAT',3,'+OK')) return false;

else

{

$this->resp=strtok($this->resp,' ');

$this->messages=strtok(' '); // 取得郵件總數(shù)

$this->size=strtok(' '); //取得總的字節(jié)大小

return true; }}

Function listmail($mess=null,$uni_id=null) //對(duì)應(yīng)的是LIST命令,取得每個(gè)郵件的大小及序號(hào)。一般來(lái)說(shuō)用到的是List命令,如果指定了$uni_id ,則使用UIDL命令,返回的是每個(gè)郵件的標(biāo)識(shí)符,事實(shí)上,這個(gè)標(biāo)識(shí)符一般是沒有什么用的。取得的各個(gè)郵件的大小返回到類的內(nèi)部變量mail_list這個(gè)二維數(shù)組里。

{if($this->state!='TRANSACTION') {

$this->err_str='還沒有連接到服務(wù)器或沒有成功登錄';

return false; }

if ($uni_id)

$command='UIDL ';

else

$command='LIST ';

if ($mess)

$command.=$mess; 

if (!$this->command($command,3,'+OK')) {

//echo $this->err_str;

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) // 取得郵件的內(nèi)容,$num是郵件的序號(hào),$line是指定共取得正文的多少行。有些時(shí)候,如郵件比較大而我們只想先查看郵件的主題時(shí)是必須指定行數(shù)的。默認(rèn)值$line=-1,即取回所有的郵件內(nèi)容,取得的內(nèi)容存放到內(nèi)部變量$head,$body兩個(gè)數(shù)組里,數(shù)組里的每一個(gè)元素對(duì)應(yīng)的是郵件源代碼的一行。

{

if($this->state!='TRANSACTION') { $this->err_str='不能收取信件,還沒有連接到服務(wù)器或沒有成功登錄';

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!='.') // . 號(hào)是郵件結(jié)束的標(biāo)識(shí) {

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)=='') // 郵件頭與正文部分的是一個(gè)空行

$is_head=false;

if ($is_head)

$this->head[]=$this->resp;

else

$this->body[]=$this->resp;

$this->getresp();

}

return true; } } // end function

function dele($num) // 刪除指定序號(hào)的郵件,$num 是服務(wù)器上的郵件序號(hào)

{

if($this->state!='TRANSACTION') {

$this->err_str='不能刪除遠(yuǎn)程信件,還沒有連接到服務(wù)器或沒有成功登錄';

return false; }

if (!$num) {

$this->err_str='刪除的參數(shù)不對(duì)';

return false; }

if ($this->command('DELE $num ',3,'+OK')) return true;

else

return false;}

通過(guò)以上幾個(gè)方法,我們已經(jīng)可以實(shí)現(xiàn)郵件的查看、收取、刪除的操作,不過(guò)別忘了最后要退出,并關(guān)閉與服務(wù)器的連接,調(diào)用下面的這個(gè)方法:

Function Close(){

if($this->connection!=0) {

if($this->state=='TRANSACTION')

$this->command('QUIT',3,'+OK');

fclose($this->connection);

$this->connection=0;

$this->state='DISCONNECTED'; }

}

標(biāo)簽: PHP
上一條: