使用PHP从POP3服务器获取邮件

41

我正在尝试从POP3(我正在使用POP3邮件服务器并尝试获取邮件内容并将其存储到数据库表中供我的项目使用)中获取邮件,但我找不到任何PHP脚本来实现。所有脚本都只适用于IMAP。

你知道如何从POP3服务器获取邮件吗?

谢谢。

5个回答

38

有些令人惊讶的是,PHP的imap库也可以用来处理POP3邮件。当然,大多数高级IMAP功能不起作用(例如文件夹或获取消息部分),但基本的POP3功能已经实现。

主要区别在于您传递给imap_open的选项字符串-引用该页面:

// To connect to a POP3 server on port 110 on the local server, use:
$mbox = imap_open ("{localhost:110/pop3}INBOX", "user_id", "password");

除此之外,一切都很顺利——你只需要使用imap_open、imap_num_msg、imap_body、imap_delete和imap_close这几个函数就足够了,用于基本的POP3访问。


11

PHP的IMAP函数可以处理IMAP和POP3邮箱。

这些函数使您能够操作IMAP协议,以及NNTP、POP3和本地邮箱访问方式。

但请注意,一些IMAP功能在使用POP协议时可能无法正常工作。

有一个用户提供的注释提供了一个有趣的片段。您可能想要看一下它。我不能说它的质量如何,但从表面上看,它看起来还不错。


以下是该注释:

对于所有希望实现以下功能的人:

1)轻松读取MIME附件,或者

2)轻松访问POP3文件夹

请看这里。

function pop3_login($host,$port,$user,$pass,$folder="INBOX",$ssl=false)
{
    $ssl=($ssl==false)?"/novalidate-cert":"";
    return (imap_open("{"."$host:$port/pop3$ssl"."}$folder",$user,$pass));
}
function pop3_stat($connection)        
{
    $check = imap_mailboxmsginfo($connection);
    return ((array)$check);
}
function pop3_list($connection,$message="")
{
    if ($message)
    {
        $range=$message;
    } else {
        $MC = imap_check($connection);
        $range = "1:".$MC->Nmsgs;
    }
    $response = imap_fetch_overview($connection,$range);
    foreach ($response as $msg) $result[$msg->msgno]=(array)$msg;

    return $result;
}
function pop3_retr($connection,$message)
{
    return(imap_fetchheader($connection,$message,FT_PREFETCHTEXT));
}
function pop3_dele($connection,$message)
{
    return(imap_delete($connection,$message));
}
function mail_parse_headers($headers)
{
    $headers=preg_replace('/\r\n\s+/m', '',$headers);
    preg_match_all('/([^: ]+): (.+?(?:\r\n\s(?:.+?))*)?\r\n/m', $headers, $matches);
    foreach ($matches[1] as $key =>$value) $result[$value]=$matches[2][$key];
    return($result);
}
function mail_mime_to_array($imap,$mid,$parse_headers=false)
{
    $mail = imap_fetchstructure($imap,$mid);
    $mail = mail_get_parts($imap,$mid,$mail,0);
    if ($parse_headers) $mail[0]["parsed"]=mail_parse_headers($mail[0]["data"]);
    return($mail);
}
function mail_get_parts($imap,$mid,$part,$prefix)
{    
    $attachments=array();
    $attachments[$prefix]=mail_decode_part($imap,$mid,$part,$prefix);
    if (isset($part->parts)) // multipart
    {
        $prefix = ($prefix == "0")?"":"$prefix.";
        foreach ($part->parts as $number=>$subpart) 
            $attachments=array_merge($attachments, mail_get_parts($imap,$mid,$subpart,$prefix.($number+1)));
    }
    return $attachments;
}
function mail_decode_part($connection,$message_number,$part,$prefix)
{
    $attachment = array();

    if($part->ifdparameters) {
        foreach($part->dparameters as $object) {
            $attachment[strtolower($object->attribute)]=$object->value;
            if(strtolower($object->attribute) == 'filename') {
                $attachment['is_attachment'] = true;
                $attachment['filename'] = $object->value;
            }
        }
    }

    if($part->ifparameters) {
        foreach($part->parameters as $object) {
            $attachment[strtolower($object->attribute)]=$object->value;
            if(strtolower($object->attribute) == 'name') {
                $attachment['is_attachment'] = true;
                $attachment['name'] = $object->value;
            }
        }
    }

    $attachment['data'] = imap_fetchbody($connection, $message_number, $prefix);
    if($part->encoding == 3) { // 3 = BASE64
        $attachment['data'] = base64_decode($attachment['data']);
    }
    elseif($part->encoding == 4) { // 4 = QUOTED-PRINTABLE
        $attachment['data'] = quoted_printable_decode($attachment['data']);
    }
    return($attachment);
}

2
在此代码示例中有一些错误(将$imap替换为$connection在pop3_stat中); 在pop3_list中返回$response..... - philippe

3

1
如果您的PHP构建支持IMAP,那么很容易实现,请参阅IMAP文档(特别是此页面上的注释)http://php.net/manual/en/book.imap.php
更新:为了澄清我的答案-正如您在评论和函数参考中看到的那样,PHP imap_*函数也可用于pop3。

0

您可以打开一个套接字连接并直接向服务器发送POP3命令以检索电子邮件。

下面的代码打开与服务器的连接,进行身份验证,请求可用消息的计数,逐个下载它们,然后从服务器中删除它们。在与服务器交互期间,如果收到意外响应,则关闭连接。

您应该能够修改下面的代码以获得所需内容。

创建一个config.ini文件并像这样填充它:

pop3_host=your.pop3.host
pop3_user=youremailusername
pop3_pass=youremailpassword

显然,将值替换为您的实际主机、用户名和密码。然后将parse_ini_file参数更改为指向您的config.ini文件。

<?php

$config = parse_ini_file('/path/to/config.ini');
$stream = fsockopen('ssl://' . $config['pop3_host'], 995, $error_code, $error_message);
if (!$stream) {
    die('fsockopen ' . $error_code . ' ' . $error_message);
}
$s = fgets($stream);
if (substr($s, 0, 3) !== '+OK') {
    quit('OPEN');
}
chat('USER ' . $config['pop3_user']);
chat('PASS ' . $config['pop3_pass']);
$s = chat('STAT');
$stat = explode(' ', $s);
if (count($stat) !== 3) {
    quit('STAT+');
}
$n = (integer)$stat[1];
for ($i = 1; $i <= $n; $i++) {
    chat('RETR ' . $i);
    $file = fopen($i . '.msg', 'wb');
    if (!$file) {
        quit('FILE ' . $i);
    }
    while (true) {
        $s = fgets($stream);
        if ($s === '.' . "\r\n") {
            fclose($file);
            break;
        }
        fputs($file, $s);
    }
    chat('DELE ' . $i);
}
chat('QUIT');
fclose($stream);

function chat(string $command): string {
    global $stream;
    fputs($stream, $command . "\r\n");
    $s = fgets($stream);
    if (substr($s, 0, 3) !== '+OK') {
        quit(explode(' ', $command)[0]);
    }
    return $s;
}

function quit(string $message): void {
    global $stream;
    fputs($stream, 'QUIT' . "\r\n");
    $s = fgets($stream);
    fclose($stream);
    die($message);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接