bxmail в 1С-Битрикс: отправка почты с учетом SMTP и событий OnBeforePhpMail

При разработке на 1С-Битрикс часто возникает необходимость отправлять письма: уведомления пользователям, системные оповещения, рассылки и пр. Стандартная функция PHP mail() работает, но в 1С-Битрикс предусмотрен более расширенный механизм, учитывающий события и внутренние настройки системы. Одной из таких функций является bxmail, определённая в файле bitrix/modules/main/tools.php. Ниже разберём, что это за функция, как она работает и в каких случаях стоит её использовать.

bxmail: отправка почты с учетом SMTP и событий OnBeforePhpMail

Основная задача функции bxmail

Функция bxmail призвана заменить встроенную функцию PHP mail() так, чтобы при отправке писем:

  1. Учитывались настройки SMTP, заданные в административной части Битрикс.
  2. Учитывались события ядра, в частности OnBeforePhpMail, позволяющие разработчикам перехватывать и модифицировать параметры перед реальной отправкой письма (например, для добавления заголовков, изменения содержания, логирования и т.д.).
  3. Выполнялась отправка через SMTP (при включенной настройке), или же стандартной функцией mail() (если SMTP не включен или не настроен).

Таким образом, bxmail делает процесс отправки писем более гибким, управляемым и соответствует рекомендациям 1С-Битрикс по кастомизации почтовой логики.

Разбор кода функции

Ниже представлен упрощённый вариант исходного кода bxmail, который находится в bitrix/modules/main/tools.php (в вашей версии Bitrix он может незначительно отличаться, но принцип тот же):


use Bitrix\Main;
use Bitrix\Main\Config\Configuration;

function bxmail($to, $subject, $message, $additional_headers = "", $additional_parameters = "", Main\Mail\Context $context = null)
{
    if (empty($context))
    {
        $context = new Main\Mail\Context();
    }

    // Событие OnBeforePhpMail – можно подписаться и изменить аргументы
    $event = new Main\Event(
        'main',
        'OnBeforePhpMail',
        [
            'arguments' => (object) [
                'to' => &$to,
                'subject' => &$subject,
                'message' => &$message,
                'additional_headers' => &$additional_headers,
                'additional_parameters' => &$additional_parameters,
                'context' => &$context,
            ],
        ]
    );
    $event->send();

    // Проверка на включенность SMTP
    $defaultMailConfiguration = Configuration::getValue("smtp");
    $smtpEnabled =
        is_array($defaultMailConfiguration)
        && isset($defaultMailConfiguration['enabled'])
        && $defaultMailConfiguration['enabled'] === true
    ;

    // Если SMTP включен — используем SMTP-мейлер
    if (
        $smtpEnabled
        && (
            $context->getSmtp() !== null
            || (!empty($defaultMailConfiguration['host']) && !empty($defaultMailConfiguration['login']))
        )
    )
    {
        $mailer = Main\Mail\Smtp\Mailer::getInstance($context);
        return $mailer->sendMailBySmtp($to, $subject, $message, $additional_headers, $additional_parameters);
    }

    // Удаляем возможные null-байты
    $message = str_replace("\0", ' ', $message);

    // Проверяем, не переопределена ли функция mail
    if(function_exists("custom_mail"))
    {
        return custom_mail($to, $subject, $message, $additional_headers, $additional_parameters, $context);
    }

    // Отправляем почту стандартным способом
    if($additional_parameters != "")
    {
        return @mail($to, $subject, $message, $additional_headers, $additional_parameters);
    }

    return @mail($to, $subject, $message, $additional_headers);
}
        

Ключевые моменты

  1. Параметр $context. Объект Main\Mail\Context хранит информацию о том, какой SMTP-сервер использовать, дополнительные настройки отправки и т.д. Если он не задан, функция создаёт новый пустой контекст.
  2. Событие OnBeforePhpMail. Позволяет подписаться на событие и изменить параметры: адрес, тему, содержимое, заголовки и т. д. Это удобно, например, чтобы встраивать свои заголовки, заменять email-получателя, протоколировать отправку в собственную таблицу логов.
  3. Проверка на использование SMTP. Функция проверяет настройки в конфиге smtp (файл /bitrix/.settings.php или .settings_extra.php, в зависимости от реализации). Если там включена отправка через SMTP, то вызывается метод sendMailBySmtp.
  4. Дополнительные возможности.
    • Проверка на наличие custom_mail позволяет переопределить стандартную логику отправки, если вы создали свою функцию с таким именем.
    • Поддержка $additional_headers и $additional_parameters позволяет передавать туда стандартные заголовки и параметры, аналогичные функции mail() в PHP.

Примеры использования

Ниже приведём несколько простых сценариев использования bxmail в коде.

1. Базовая отправка письма


<?php
$to = "user@example.com";
$subject = "Тестовое письмо из Bitrix";
$message = "Привет! Это текстовое содержимое письма.";
$headers = "From: no-reply@mydomain.ru\r\n";  // Дополнительные заголовки

bxmail($to, $subject, $message, $headers);
        

В этом случае:

  • Письмо отправится либо через SMTP, если это настроено, либо через стандартную функцию mail.
  • Если у вас есть обработчики события OnBeforePhpMail, они сработают, и смогут модифицировать параметры.

2. Отправка HTML-письма

Часто требуется отправить HTML-контент, например, письмо-рассылку с версткой.


<?php
$to = "user@example.com";
$subject = "HTML-письмо";
$message = "<html><body><h1>Заголовок</h1><p>Это <b>HTML</b> письмо!</p></body></html>";

// Обязательно указываем заголовок типа контента и кодировку
$headers = "From: info@mydomain.ru\r\n";
$headers .= "Content-type: text/html; charset=UTF-8\r\n";

bxmail($to, $subject, $message, $headers);
        

Совет: Следите за корректным форматом заголовков: Content-type: text/html; charset=UTF-8, а также за тем, чтобы все строки заголовков разделялись \r\n.

3. Дополнительные параметры функции mail

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


<?php
$to = "user@example.com";
$subject = "Проверка Return-Path";
$message = "Это тест.";

$headers = "From: My Site <info@mydomain.ru>\r\n";
$additionalParameters = "-f info@mydomain.ru"; // Return-Path

bxmail($to, $subject, $message, $headers, $additionalParameters);
        

Когда SMTP включен, этот параметр для mail() может игнорироваться, но при неиспользовании SMTP возвращает нам знакомый механизм явного указания Return-Path.

4. Использование собственного обработчика почты

Допустим, вы определили пользовательскую функцию custom_mail, которая логирует письма в Битрикс-журнал или CRM, а только потом отправляет. Если она существует, то bxmail будет вызывать именно её:


<?php
function custom_mail($to, $subject, $message, $headers, $additional_parameters, $context)
{
    // Логируем
    file_put_contents(__DIR__ . '/mail_log.txt', date('Y-m-d H:i:s')
        . " - " . $to . " | " . $subject . "\n", FILE_APPEND);

    // Далее, по желанию, отправляем стандартной функцией
    return mail($to, $subject, $message, $headers, $additional_parameters);
}
        

При наличии такой функции вызов bxmail() перенаправится в ваш custom_mail.

5. Подписка на событие OnBeforePhpMail

Чтобы модифицировать письмо на уровне события, достаточно подписаться на OnBeforePhpMail в файле init.php или создать собственный модуль. Пример (упрощённый):


<?php
AddEventHandler("main", "OnBeforePhpMail", "modifyMail");

function modifyMail(\Bitrix\Main\Event $event)
{
    // Получаем объект аргументов
    $arguments = $event->getParameter('arguments');

    // Например, заменим адрес получателя
    $arguments->to = "manager@example.com";

    // Добавим префикс к теме
    $arguments->subject = "[MyProject] " . $arguments->subject;

    // Добавим постскриптум в тело
    $arguments->message .= "\n\n--\nP.S. Это было модифицировано через OnBeforePhpMail.";
}
        

При вызове bxmail эти изменения будут учтены до фактической отправки.

Возможные ошибки и их устранение

  1. Неверно указана кодировка: Если забыть заголовок Content-type: text/html; charset=UTF-8, пользователи могут получать «кракозябры» в письме или HTML в виде текста. Решение – всегда правильно формировать заголовки при отправке письма.
  2. Отсутствует \r\n: В заголовках письма нужно использовать стандарт \r\n, а не просто \n. Иначе часть почтовых серверов может неправильно прочитать заголовки.
  3. Не срабатывает SMTP: Убедитесь, что в настройках 1С-Битрикс (раздел «Настройки > Настройки модулей > Почта и SMS») SMTP включен и корректно заполнены поля host, login, password. Также проверьте .settings.php или .settings_extra.php, где могут храниться эти настройки.
  4. Обработчик события не вызывается: Убедитесь, что ваш обработчик зарегистрирован после инициализации модулей (например, в init.php). Также проверьте правильность названия события ("main", "OnBeforePhpMail") и сигнатуры AddEventHandler.

Заключение

Функция bxmail — это удобная надстройка над стандартным mail(), которая позволяет:

  • Гибко подключать SMTP без дополнительных библиотек.
  • Подключать обработчики OnBeforePhpMail, изменяя логику отправки на лету.
  • Переопределять логику отправки через собственную функцию custom_mail.
  • Контролировать заголовки и параметры отправки так же, как и в обычном PHP.

При разработке на 1С-Битрикс рекомендуется пользоваться именно bxmail, чтобы соответствовать обновлённым стандартам ядра, учитывать внутренние события, а также не ломать совместимость с будущими версиями продукта. Если вы хотите настроить сложные сценарии отправки (включая массовые рассылки, трекинг открытий, метрики кликов), лучше расширять существующий функционал, используя события и, при необходимости, собственные классы, но в основе которых по-прежнему будет лежать bxmail.

Теги:  bxmail, отправка почты, SMTP, OnBeforePhpMail, PHP, mail

Стоимость услуг по разработке и сопровождению сайтов на 1C-Битрикс

Лендинг

от 3 дней

от 25 000 рублей

Разработка одностраничного сайта на платформе Битрикс

* стоимость зависит от наличия верстки, использования готового решения и т.д.

Техническая поддержка

выполняется с сайтами на основе любых CMS

от 5 000 рублей
Оптимизация производительности действующих интернет-проектов, наполнение и сопровождение, полная техническая поддержка и продвижение в поисковых сетях.

* стоимость зависит от объема и сложности выполняемых работ, используемой CMS.

Участие в проекте

привлечение в проект на part-time основе

от 20 000 рублей / неделя

Возможно участие в проекте на ежедневной основе, как разработчика. Занятость - до 20 часов в неделю
Минимальный срок - одна неделя.

* сумма фиксированная