0

0

用PHP实现POP3邮件的收取(二)

php中文网

php中文网

发布时间:2016-05-19 14:05:26

|

1047人浏览过

|

来源于php中文网

原创

用php实现pop3收取邮件的类

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

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

1.成员变量说明

立即学习PHP免费学习笔记(深入)”;

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

{

小邮包 包月订购包年程序
小邮包 包月订购包年程序

小邮包-包月订购包年服务网,该程序由好买卖商城开发,程序采用PHP+MYSQL架设,程序商业模式为目前最为火爆的包月订制包年服务模式,这种包年订购在国外网站已经热火很多年了,并且已经发展到一定规模,像英国的男士用品网站BlackSocks,一年的袜子购买量更是达到了1000万双。功能:1、实现多产品上线,2、不用注册也可以直接下单购买,3、集成目前主流支付接口,4、下单发货均有邮件提醒。

下载

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

$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速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法
pixiv网页版官网登录与阅读指南_pixiv官网直达入口与在线访问方法

本专题系统整理pixiv网页版官网入口及登录访问方式,涵盖官网登录页面直达路径、在线阅读入口及快速进入方法说明,帮助用户高效找到pixiv官方网站,实现便捷、安全的网页端浏览与账号登录体验。

616

2026.02.13

微博网页版主页入口与登录指南_官方网页端快速访问方法
微博网页版主页入口与登录指南_官方网页端快速访问方法

本专题系统整理微博网页版官方入口及网页端登录方式,涵盖首页直达地址、账号登录流程与常见访问问题说明,帮助用户快速找到微博官网主页,实现便捷、安全的网页端登录与内容浏览体验。

194

2026.02.13

Flutter跨平台开发与状态管理实战
Flutter跨平台开发与状态管理实战

本专题围绕Flutter框架展开,系统讲解跨平台UI构建原理与状态管理方案。内容涵盖Widget生命周期、路由管理、Provider与Bloc状态管理模式、网络请求封装及性能优化技巧。通过实战项目演示,帮助开发者构建流畅、可维护的跨平台移动应用。

91

2026.02.13

TypeScript工程化开发与Vite构建优化实践
TypeScript工程化开发与Vite构建优化实践

本专题面向前端开发者,深入讲解 TypeScript 类型系统与大型项目结构设计方法,并结合 Vite 构建工具优化前端工程化流程。内容包括模块化设计、类型声明管理、代码分割、热更新原理以及构建性能调优。通过完整项目示例,帮助开发者提升代码可维护性与开发效率。

20

2026.02.13

Redis高可用架构与分布式缓存实战
Redis高可用架构与分布式缓存实战

本专题围绕 Redis 在高并发系统中的应用展开,系统讲解主从复制、哨兵机制、Cluster 集群模式及数据分片原理。内容涵盖缓存穿透与雪崩解决方案、分布式锁实现、热点数据优化及持久化策略。通过真实业务场景演示,帮助开发者构建高可用、可扩展的分布式缓存系统。

54

2026.02.13

c语言 数据类型
c语言 数据类型

本专题整合了c语言数据类型相关内容,阅读专题下面的文章了解更多详细内容。

29

2026.02.12

雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法
雨课堂网页版登录入口与使用指南_官方在线教学平台访问方法

本专题系统整理雨课堂网页版官方入口及在线登录方式,涵盖账号登录流程、官方直连入口及平台访问方法说明,帮助师生用户快速进入雨课堂在线教学平台,实现便捷、高效的课程学习与教学管理体验。

15

2026.02.12

豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法
豆包AI网页版入口与智能创作指南_官方在线写作与图片生成使用方法

本专题汇总豆包AI官方网页版入口及在线使用方式,涵盖智能写作工具、图片生成体验入口和官网登录方法,帮助用户快速直达豆包AI平台,高效完成文本创作与AI生图任务,实现便捷智能创作体验。

598

2026.02.12

PostgreSQL性能优化与索引调优实战
PostgreSQL性能优化与索引调优实战

本专题面向后端开发与数据库工程师,深入讲解 PostgreSQL 查询优化原理与索引机制。内容包括执行计划分析、常见索引类型对比、慢查询优化策略、事务隔离级别以及高并发场景下的性能调优技巧。通过实战案例解析,帮助开发者提升数据库响应速度与系统稳定性。

56

2026.02.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号