Пересылка писем с помощью скрипта PHP - PullRequest
8 голосов
/ 22 декабря 2010

У нас есть cron'ed PHP-скрипт, который проверяет входящие сообщения каждые десять минут. Целью этого скрипта является обработка функции «STOP для выхода» для нашего сервиса SMS-уведомлений, который мы предоставляем. Если сценарий находит какие-либо электронные письма со словом «СТОП» в начале электронного письма, мы удаляем пользователя из нашей базы уведомлений.

Чтобы охватить наши базы, мы хотели бы, чтобы любые электронные письма, которые не соответствуют вышеуказанным критериям, пересылались на другой адрес электронной почты (который является псевдонимом), который несколько человек получают и проверяют ежечасно. Однако у нас возникают проблемы с пересылкой писем из этого сценария PHP.

Зная, как работает mail функция PHP, совершенно очевидно, что нам нужно заново вставить заголовки перед отправкой по почте. Однако составные электронные письма MIME всегда отправляются в виде искаженного текста, включая барьеры и любые вложения, закодированные в base64.

Кто-нибудь знает простой способ получить сообщение электронной почты и правильно переслать его, используя скрипт PHP?

Мы используем встроенные функции IMAP, встроенные в PHP 5. У нас также есть доступ к модулю PEAR Mail. Однако мы не смогли найти ни одного примера или людей, выполняющих аналогичные задачи, выполнив поиск в Google.

Ответы [ 5 ]

6 голосов
/ 11 января 2011

Я давно кодировал этот метод, чтобы разобрать сообщение электронной почты в соответствующие части с помощью 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 нетронутыми.

4 голосов
/ 22 декабря 2010

Это на самом деле не ответ, а предложение альтернативного метода. Я думаю, что было бы намного проще и менее подвержено ошибкам (то есть, никаких проблем с доставкой), если бы вы просто перемещали сообщения в разные папки существующей учетной записи. Т.е., cron запускает и обрабатывает все электронные письма в INBOX. Если if находит STOP, он выполняет требуемую работу, а затем (через функции IMAP) просто перемещает электронное письмо в подпапку с именем «Обработано» или аналогичную. В противном случае он перемещает электронное письмо в подпапку с именем «Проверить эти» или аналогичную. Тогда вам не нужно беспокоиться о переадресации, дальнейших доставках или второй учетной записи, и каждый может непосредственно отслеживать обработанные, необработанные и ожидающие сообщения.

1 голос
/ 22 декабря 2010

Это случилось со мной раньше. Чтобы это исправить, мне нужно было выполнить imap_base64 () в теле письма после того, как я использовал imap_fetchbody ().

$body = imap_fetchbody($imap, 1, 1);
$headers = imap_headerinfo($imap, 1);
$body = imap_base64($body);
1 голос
/ 22 декабря 2010

Вы ознакомились с функциональностью, используя библиотеку Swiftmailer ?

http://swiftmailer.org/

Я использовал это в прошлом и получил хороший результатХотя не в приложении, как вы описали, я использовал его для «списков рассылки» на основе PHP, где я проверил тему и отправил в соответствующую группу.

Но я создал новое сообщение, не переадресовал,Надеюсь, это поможет.

0 голосов
/ 10 октября 2014

используйте обработчик ввода-вывода, чтобы захватить содержимое письма в виде строки, разделить заголовки, а затем использовать функцию php 'mail ()' для отправки.

Иначе, если вы действительно хотите сделать это с php-imap,

расширение php-imap - это libc-client, который является частью программного обеспечения почтового клиента pine выясните, какие шаги необходимо выполнить вручную с помощью pine, а затем посмотрите на вызовы c-client, которые делает pine для этого. это даст вам шаги, необходимые в php.

документация c-client довольно минимальна, лучше всего узнать подробности об использовании исходного кода сосны.

Я думаю, вы можете обнаружить, что автор расширения php "для вашего удобства или защиты" пропустил или изменил материал, блокирующий этот путь.

...