用php实现POP3收取邮件的类

现在让我们来用PHP实现一个通过POP3协议收取信件的类吧,这个类中所用到的一些sock操作的函数,不另做特殊说明,请参考php的有关资料。通过这个实例,相信你也会和我一样,感觉到PHP中对于sock操作的灵活、方便和功能的强大。

首先,我们来说明一下这个类中需要用到的一些内部成员变量:(这些变量应该都是对外封闭的,可是由于php对类的成员变量没有PRivate与publice之类的分别,只好就这么直接定义了。这是PHP的一个令人遗憾的地方。)

1.成员变量说明

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(); // 邮件体的内容,数组;

2.当然,这其中的有些变量,仅通过这样一个简单的说明并不能完全了解如何使用,下面我就逐个来说明这个类实现中的一些主要方法:

Function pop3($server="192.100.100.1",$port=110,$time_out=5)

{$this->hostname=$server;

$this->port=$port;

$this->timeout=$time_out;

return true;

}

熟悉面向对象编程的朋友一看就会知道,这是这个类的构造函数,在初始化这个类时,可以给出这几个最基本的参数:pop3服务器的地址,端口号,及连接服务器时的最大超时时间。一般来说,只需要给出POP3服务器的地址就行了。

Function open()

{

if($this->hostname=="")

{$this->err_str="无效的主机名!!";

return false;

}

if ($this->debug) echo "正在打开 $this->hostname,$this->port,&$err_no, &$err_str, $this->timeout

";

if (!$this->connection=fsockopen($this->hostname,$this->port,&$err_no, &$err_str, $this->timeout))

{

$this->err_str="连接到POP服务器失败,错误信息:".$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;

}

}

该方法不需要任何参数就可建立与POP3服务器的sock连接。该方法又用到了另一个类中的方法$this->getresp();下面是这个方法的声明:

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)."

\n";

}

它的作用就是把调试信息$message显示出来,并把一些特殊字符进行转换以及在行尾加上

标签,这样是为了使其输出的调试信息便于阅读和分析。

建立起与服务器的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

{

//echo $this->resp=strtok($this->resp,"\r\n");

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

}

$this->state="TRANSACTION"; // 用户认证通过,进入传送模式

return true;

}

Function stat() // 对应着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) //对应的是LIST命令,取得每个邮件的大小及序号。一般来说用到的是List命令,如果指定了$uni_id ,则使用UIDL命令,返回的是每个邮件的标识符,事实上,这个标识符一般是没有什么用的。取得的各个邮件的大小返回到类的内部变量mail_list这个二维数组里。

{

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"))

{

//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) // 取得邮件的内容,$num是邮件的序号,$line是指定共取得正文的多少行。有些时候,如邮件比较大而我们只想先查看邮件的主题时是必须指定行数的。默认值$line=-1,即取回所有的邮件内容,取得的内容存放到内部变量$head,$body两个数组里,数组里的每一个元素对应的是邮件源代码的一行。

{

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) // 删除指定序号的邮件,$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";

}

}

PHP实现pop3,用PHP实现POP3邮件的收取(二)相关推荐

  1. 用PHP实现POP3邮件的收取(一)

    POP协议简介 本文简要说明了通过POP3协议收取邮件.MIME邮件的解码的原理:针对收取和MIME解码,提供了两个实用的PHP类,并提供了运用的样例.分为邮件收取.MIME解码两个部分.这里我们先向 ...

  2. JavaMail 使用POP3/SMTP服务发送QQ邮件

    目录 一.说明 二.理解 三.实现 1.导入jar包 2.用户认证 3.发送邮件 创建步骤 简单的Email 带HTML的E-mail 带图片的Email 包含附件的邮件 一.说明 邮件服务器 为用户 ...

  3. Python利用POP3/SMTP服务自动发送qq邮件

    自动发送qq邮件的两种方法 第一种:POP3/SMTP服务发送qq邮件 废话不多说,直接上代码. # coding:utf-8 import smtplib from email.mime.text ...

  4. spring boot 中使用 POP3协议读取并解析邮件

    spring boot 中使用 POP3协议读取并解析邮件 1.邮箱授权 QQ邮箱授权,打开 "设置" 切换到 "账户" 找到下图中设置,开启 "PO ...

  5. 基于C#平台下利用POP3和SMTP协议的邮件归档系统

    今天对电脑进行整理,发现电脑上有一个帮同学做的毕设代码,挺简单的,但是当成做的时候吃了不少苦头,现在都毕业了,就放上来给新手分享一下.好了话不多说. 首先了解一下POP3和SMTP协议,他们是两个网络 ...

  6. pop3 postfix 命令_postfix+pop3+imap+cyrus

    1.安装postfix软件包 2.安装smtp认证包 3.安装pop3和imap服务包 4.安装webmail软件包(webmail需要web服务器的支持) Postfix 一.Postfix邮件服务 ...

  7. Linux卸载雷鸟邮件客户端,Ubuntu上怎么设置雷鸟邮件客户端收取QQ邮箱邮件?

    有时候我们在使用Ubuntu的时候,需要频繁的登录web网页来收取QQ收件,这样很麻烦.其实我们可以用系统自带的"雷鸟邮件"客户端来收取QQ邮箱的邮件. 打开dash,输入thun ...

  8. android pop3与imap方式接收邮件(javamail)

    需要下载3个jar包:mail.jar/    activation.jar/    additionnal.jar 1.pop3 /** * 以pop3方式读取邮件,此方法不能读取邮件是否为已读,已 ...

  9. PHP+socket+SMTP、POP3协议发送、接收邮件

    1.实现SMTP协议的类dsmtp.cls.php: <?php            // 通过socket实现SMTP协议的功能 // version: 1.1 // author : DC ...

  10. exchange无法收发邮件_Python使用POP3和SMTP协议收发邮件!

    先来了解一下收/发邮件有哪些协议: SMTP协议 SMTP(Simple Mail Transfer Protocol),即简单邮件传输协议.相当于中转站,将邮件发送到客户端. POP3协议 POP3 ...

最新文章

  1. 大赛归来的你们,仍是那个少年--少了游移、多了自信,少了软弱、多了坚强...
  2. 头文件的包含以及命名空间的引入尽量写在cpp里
  3. 许式伟《Go语言编程》章节摘录:Go语言简史
  4. 明晚直播丨MySQL的查询与优化
  5. 常用正则表达式知识点解读及判读有效数字、手机号邮箱正则表达式
  6. [转] Windows完成端口与Linux epoll技术简介
  7. 【踩坑速记】二次依赖?android studio编译运行各种踩坑解决方案,杜绝弯路,总有你想要的~...
  8. thinkphp LoginAction.class.php 登录模块
  9. SOCKET 478/775是两种主板的CPU接口类型
  10. 前端实战|React18项目启动——pc端极客园项目前置准备
  11. 基于p5实现的大五人格“线条”效果
  12. 两数求和(C语言超简单解法)
  13. uva 571 Jugs
  14. 用思维导图快速学语法
  15. 图像处理(7)--高斯模糊原理
  16. java固件包_iOS13 各版本固件下载地址以及更新方法
  17. inter酷睿后缀含义
  18. jenkins html插件,Jenkins插件HTML Publisher Plugin的使用
  19. 【Python】《点燃我,温暖你》李峋同款爱心_python程序
  20. #叉积#zoj 1041 poj 1106 ssl 1232 雷达覆盖问题 Transmitters

热门文章

  1. 【PyCharm 使用指南】之汉化插件(官方提供)
  2. 软件测试报告 图书管理系统,图书管理系统报告 图书馆管理系统报告
  3. 海康威视h5无插件播放解决方案
  4. Git工作流(简单)
  5. en55032最新标准下载_欧盟新EMC标准EN55032将强制实施
  6. 免疫算法小结及算法实例(附Matlab代码)
  7. STEP7 MicroWIN SMART 下载程序到CPU的具体步骤详解(图文)
  8. C语言编程必背单词百度云,c语言编程必背单词-20210403022023.pdf-原创力文档
  9. wacom linux 驱动下载,Ubuntu 8.04如何安装WACOM驱动
  10. C语言 100道经典编程题适用于专升本,专接本【详细分析版】