9

我们有一个 cron'ed PHP 脚本,它每十分钟检查一次收件箱。此脚本的目的是为我们提供的 SMS 通知服务处理“停止退出”功能。如果脚本在电子邮件开头找到任何带有“STOP”字样的电子邮件,我们会将用户从通知数据库中删除。

为了覆盖我们的基础,我们希望将任何不符合上述标准的电子邮件转发到另一个电子邮件地址(这是一个别名),由几个人每小时接收和检查一次。但是,我们在从这个 PHP 脚本转发电子邮件时遇到了问题。

了解了mailPHP 的功能是如何工作的,很明显我们需要在发送邮件之前重新插入标头。但是,MIME 多部分电子邮件总是作为乱码发送,包括障碍和任何 base64 编码的附件。

有谁知道一种简单的方法来获取电子邮件并使用 PHP 脚本正确转发它?

我们使用 PHP 5 中内置的本地 IMAP 函数。我们还可以访问 PEAR Mail 模块。但是,我们无法通过搜索 Google 找到任何示例或执行类似任务的人。

4

5 回答 5

6

很久以前,我编写了这个方法来使用 IMAP 将电子邮件消息解析为适当的部分:

function Message_Parse($id)
{
    if (is_resource($this->connection))
    {
        $result = array
        (
            'text' => null,
            'html' => null,
            'attachments' => array(),
        );

        $structure = imap_fetchstructure($this->connection, $id, FT_UID);

        if (array_key_exists('parts', $structure))
        {
            foreach ($structure->parts as $key => $part)
            {
                if (($part->type >= 2) || (($part->ifdisposition == 1) && ($part->disposition == 'ATTACHMENT')))
                {
                    $filename = null;

                    if ($part->ifparameters == 1)
                    {
                        $total_parameters = count($part->parameters);

                        for ($i = 0; $i < $total_parameters; $i++)
                        {
                            if (($part->parameters[$i]->attribute == 'NAME') || ($part->parameters[$i]->attribute == 'FILENAME'))
                            {
                                $filename = $part->parameters[$i]->value;

                                break;
                            }
                        }

                        if (is_null($filename))
                        {
                            if ($part->ifdparameters == 1)
                            {
                                $total_dparameters = count($part->dparameters);

                                for ($i = 0; $i < $total_dparameters; $i++)
                                {
                                    if (($part->dparameters[$i]->attribute == 'NAME') || ($part->dparameters[$i]->attribute == 'FILENAME'))
                                    {
                                        $filename = $part->dparameters[$i]->value;

                                        break;
                                    }
                                }
                            }
                        }
                    }

                    $result['attachments'][] = array
                    (
                        'filename' => $filename,
                        'content' => str_replace(array("\r", "\n"), '', trim(imap_fetchbody($this->connection, $id, ($key + 1), FT_UID))),
                    );
                }

                else
                {
                    if ($part->subtype == 'PLAIN')
                    {
                        $result['text'] = imap_fetchbody($this->connection, $id, ($key + 1), FT_UID);
                    }

                    else if ($part->subtype == 'HTML')
                    {
                        $result['html'] = imap_fetchbody($this->connection, $id, ($key + 1), FT_UID);
                    }

                    else
                    {
                        foreach ($part->parts as $alternative_key => $alternative_part)
                        {
                            if ($alternative_part->subtype == 'PLAIN')
                            {
                                echo '<h2>' . $alternative_part->subtype . ' ' . $alternative_part->encoding . '</h2>';

                                $result['text'] = imap_fetchbody($this->connection, $id, ($key + 1) . '.' . ($alternative_key + 1), FT_UID);
                            }

                            else if ($alternative_part->subtype == 'HTML')
                            {
                                echo '<h2>' . $alternative_part->subtype . ' ' . $alternative_part->encoding . '</h2>';

                                $result['html'] = imap_fetchbody($this->connection, $id, ($key + 1) . '.' . ($alternative_key + 1), FT_UID);
                            }
                        }
                    }
                }
            }
        }

        else
        {
            $result['text'] = imap_body($this->connection, $id, FT_UID);
        }

        $result['text'] = imap_qprint($result['text']);
        $result['html'] = imap_qprint(imap_8bit($result['html']));

        return $result;
    }

    return false;
}

我从来没有深入测试过它,我确信它有一些错误,但这可能是一个开始......在调整了这段代码之后,你应该能够在你的转发脚本中使用$result索引(text, html, attachments)(使用 SwiftMailer例如),而不必担心保持 MIME 边界完整。

于 2011-01-10T22:55:12.117 回答
4

这并不是真正的答案,而是对替代方法的建议。我认为,如果您只是将邮件移动到现有帐户中的不同文件夹,它会更简单且更不容易出错(即没有传递问题)。即,cron 运行并处理收件箱中的所有电子邮件。如果找到 STOP,它会执行所需的工作,然后(通过 IMAP 函数)简单地将电子邮件移动到名为“Processed”或类似名称的子文件夹中。否则,它将电子邮件移动到名为“检查这些”或类似名称的子文件夹中。这样您就无需担心转发、进一步投递或第二个帐户,每个人都可以直接监控已处理、未处理和待处理的邮件。

于 2010-12-21T21:28:17.500 回答
1

您是否看过使用Swiftmailer库的功能?

http://swiftmailer.org/

我过去曾使用过它并取得了不错的效果,尽管不是在您所描述的应用程序中,但是我已将其用于基于 PHP 的“邮件列表”,在其中我检查了主题并将其发送到适当的组。

但是我创建了一条新消息,没有转发。希望有帮助。

于 2010-12-21T21:22:51.377 回答
1

这以前发生在我身上。为了解决这个问题,我必须在使用 imap_fetchbody() 之后在电子邮件正文上执行 imap_base64()。

$body = imap_fetchbody($imap, 1, 1);
$headers = imap_headerinfo($imap, 1);
$body = imap_base64($body);
于 2010-12-21T21:34:09.233 回答
0

使用 IO 处理程序将电子邮件的内容捕获为字符串,拆分标题,然后使用 php 'mail()' 函数发送它。

否则,如果你真的想用 php-imap 来做这件事,

php-imap 扩展是 libc-client,它是 pine 电子邮件客户端软件的一部分,找出使用 pine 执行此操作所需的手动步骤,然后查看 pine 执行此操作所需的 c-client 调用。这将为您提供 php.ini 所需的步骤。

c-client 文档相当少,访问 pine 源代码是获取使用详细信息的最佳方式。

我想您可能会发现 php 扩展的作者“为了您的方便或保护”省略或更改了阻止此路径的内容。

于 2014-10-10T02:12:08.723 回答