Как расширить MailboxHeader.php в Swift Mailer или проверить электронную почту

Я работаю с SYmfony 1.4 и быстрой почтовой программой для отправки большого количества электронных писем через Sendgrid.

Я получаю сообщение об ошибке соответствия RFC для некоторых адресов электронной почты.

Одним из решений может быть удаление условия для выдает ошибку, и это работает, но требует замены ядра. Как бы вы расширили MailboxHeader.php в файлах сайта, а не в ядре symfony. Что-то вроде этого, но не так, потому что это не работает:

class overrideRFCError extends Swift_Mime_Headers_AbstractHeader
{
    private function _assertValidAddress($address)
    {
        if (!preg_match('/^' . $this->getGrammar('addr-spec') . '$/D',
          $address))
        {
          // throw new Swift_RfcComplianceException(
          //   'Address in mailbox given [' . $address .
          //   '] does not comply with RFC 2822, 3.6.2.'
          //   );
        }
    }
}

Это также кажется немного тяжелым. Есть ли способ проверить электронную почту на соответствие RFC. Если это так, я мог бы просто удалить его из массива.

ОБНОВЛЕНИЕ 17.07.13

Я смог провести тщательную очистку каждого адреса, чтобы сделать его совместимым с RFC, что решило проблему. Однако я хотел бы знать, существует ли в SwiftMailer функция, которая выполняет эту проверку, а не пишет пользовательскую функцию.

ОБНОВЛЕНИЕ 18.07.13

Вот что я получил на работу. Я старался максимально очистить записи.

Загрузите массив адресов в переменную с именем $emailList

в действиях:

$cleanList = sendGridEmailer::validateEmails($emailList);

в классе sendGridEmailer:

// loop and validate each email address
    public static function validateEmails($emailList) {
        foreach($emailList as $address => $name) {
            try {
                $v = new sfValidatorEmail();
                $email = $v->clean($address);

            } catch (sfValidatorError $e) {
                unset($emailList[$address]);
            }
        }
        foreach($emailList as $address => $name) {
            $rfcTesting = validateEmailForRFC::is_email($address);
            if(!$rfcTesting) {
                unset($emailList[$address]);
            }
            if (!preg_match('/^[a-zA-Z0-9_.-@]/', $address)) {
                unset($emailList[$address]);
            }
        }
        // List should be clean
        return $emailList;
    }

Таким образом, сначала используется sfValidator для удаления начальных плохих адресов. Затем я получил сценарий соответствия RFC здесь и выполнил его в классе validateEmailForRFC, что должно сделать их совместимыми с RFC. .

Наконец, я делаю финальное предварительное сопоставление для всех отставших со странными символами, которые не были обнаружены предыдущими проверками.

Это позволило мне сохранить ядро ​​Symfony нетронутым и подготовить адреса для Swift без ошибок соответствия.


person Carey Estes    schedule 16.07.2013    source источник
comment
Есть ли у вас какие-либо подробности об адресах, которые вызывают ошибку? Предотвращение ошибки путем переопределения может быть обходным путем, но не решением.   -  person Sven Schneider    schedule 16.07.2013
comment
На самом деле шансов избежать этого практически нет. Проверка на неправильные адреса соответствует RFC, хотя провайдеры могут принять это. Правила проверки жестко запрограммированы в Swift. Меняйте ядро, не выкидывайте ошибку, а пишите в лог-файл адрес. Таким образом, вы можете проверить, неправильный ли адрес или это просто строгая проверка.   -  person Sven Schneider    schedule 16.07.2013
comment
Я бы предпочел не удалять проверку ошибок. Я думаю, что есть функция SwiftMailer, которая проверяет RFC-валидацию. Это существует?   -  person Carey Estes    schedule 16.07.2013
comment
Проблема во внутренней проверке SwiftMailer. У вас нет параметров для включения/выключения этой проверки. Многие люди сталкиваются с этой проблемой, команда SwiftMailer говорит, что знает об этом, но строгая проверка лучше и надежнее, чем любая слабая проверка. Так что только обходные пути будут работать.   -  person Sven Schneider    schedule 17.07.2013
comment
Хорошее решение, но я думаю, что тогда я не понимаю вашей проблемы. Это больше с точки зрения продукта, чем с точки зрения программиста. Если у вас есть почтовые адреса в базе данных, на которую вы хотите отправлять почту, обычно это адреса пользователей. Пользователи вводили их где-то на вашем сайте. Либо в этот момент должна произойти проверка, либо самое позднее при согласии пользователя. Неверный адрес электронной почты -› нет письма для подписки -› нет мусора в базе данных. Но мне нравится ваше решение, нужно иметь это в виду.   -  person Sven Schneider    schedule 17.07.2013
comment
@Sven В идеальном мире ты прав. пользователь будет загружать действительное электронное письмо, и будет процесс проверки на уровне отправки. Тем не менее, есть и умные маленькие роботы, которые усердно работают над нарушением проверки отправки. Мы также извлекаем данные из базы данных, которая представляет собой коллекцию, накопленную за ~10 лет. Мое вторичное решение состояло в том, чтобы создать cron, который будет проверять и удалять все недопустимые помеченные адреса.   -  person Carey Estes    schedule 18.07.2013


Ответы (1)


Вы можете использовать функцию Symfony sfValidatorEmail или функцию filter-var. Они достаточно хорошо работают с SwiftMailer, но ни один из них не соответствует требованиям RFC IIRC. Для проверки соответствия RFC вы можете использовать https://github.com/egulias/EmailValidator или https://github.com/dominicsayers/isemail.

person 1ed    schedule 16.07.2013
comment
Проблема не в том, что проверка не выполняется. Встроенная проверка SwiftMailer соответствует RFC, и это слишком строго для многих почтовых провайдеров, которые разрешают менее строгие адреса (локальная часть адреса электронной почты). - person Sven Schneider; 17.07.2013
comment
Поскольку SwiftMailer проверяет адреса электронной почты перед отправкой электронного письма и выдает исключение, если оно недействительно, поэтому вы должны проверять электронные письма перед их вставкой в ​​​​базу данных или перед отправкой электронного письма. При отправке только одному получателю вы можете использовать try ... catch, но для массовой отправки это не так хорошо. - person 1ed; 17.07.2013
comment
Проверка IIRC SwiftMailer's на самом деле более строгая, чем RFC, например. isemail.info/root%40localhost не работает в SwiftMailer IIRC... и это может быть проблемой, поскольку пользователь с экзотическими адресами электронной почты, но в целом все в порядке. - person 1ed; 17.07.2013