Přepracování odesílání e-mailů pomocí PHP: Hluboký ponor do návrhu tříd a zpracování chyb

Při vývoji robustní funkce odesílání e-mailů v jazyce PHP je zásadní využití tříd a správných mechanismů pro ošetření chyb. Nedávno jsem pracoval na zdokonalení třídy pro odesílání e-mailů pro jeden ze svých projektů. Tento článek podrobně popisuje tento proces, včetně použití PHPMailer pro odesílání e-mailů a implementace metod pro efektivní zpracování e-mailových adres.

Počáteční nastavení: Definování třídy EmailStaticSender

Nejprve potřebujeme třídu, která se stará o odesílání e-mailů. Použijeme PHPMailer, populární knihovnu pro odesílání e-mailů v jazyce PHP. Zde je počáteční nastavení naší třídy:

<?php

namespace APK_NAME\Core\SystemStatic;

use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use APK_NAME\Core\SystemCore\LC;
use APK_NAME\Core\SystemCore\Swal;

// DEV: základní ošetření přihlášení
if (!defined('MY_APP_STARTED')) {
    exit;
}

class EmailStaticSender
{
    private static $recipient;
    private static $subject;
    private static $message;
    private static $html;
    private static $attachment;
    private static $separateEmail;

    public static function init($recipient, $subject, $message, $html = false, $filePath = null, $separateEmail = false): void
    {
        self::$recipient = $recipient;
        self::$subject = $subject;
        self::$message = $message;
        self::$html = $html;
        self::$attachment = $filePath;
        self::$separateEmail = $separateEmail;
    }

    // Další metody budou následovat
}

Odesílání e-mailů pomocí PHPMailer

Pro odesílání e-mailů vytvoříme metodu send. Tato metoda konfiguruje a používá PHPMailer k odesílání e-mailů. Zahrnuje zpracování chyb, které zachytí případné problémy během procesu odesílání e-mailů.

public static function send(): bool
{
    if (USE_PHPMAILER) {
        $mail = new PHPMailer(true);
        try {
            $mail->isSMTP();
            $mail->Host = SMTP_HOST;
            $mail->SMTPAuth = true;
            $mail->CharSet = 'UTF-8';
            $mail->Username = SMTP_USERNAME;
            $mail->Password = SMTP_PASSWORD;
            $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
            $mail->Port = SMTP_PORT;
            $mail->setFrom(MAIL_FROM_ADDRESS, MAIL_FROM_NAME);
            $mail->addReplyTo(REPLY_TO_ADDRESS, REPLY_TO_NAME);
            $mail->isHTML(self::$html);
            $mail->Subject = self::$subject;
            $mail->Body = self::$message;
            if (self::$attachment) {
                $mail->addAttachment(self::$attachment);
            }

            $recipients = explode(';', self::$recipient);
            if (empty($recipients) || self::$recipient == 'FAIL') {
                return false;
            }
            if (self::$separateEmail) {
                foreach ($recipients as $recipient) {
                    $mail->addAddress(trim($recipient));
                    $mail->send();
                    $mail->clearAddresses();
                }
            } else {
                foreach ($recipients as $recipient) {
                    $mail->addAddress(trim($recipient));
                }
                if (DEVELOPER_ENVIRONMENT) {
                    error_log(json_encode($recipients));
                    error_log(json_encode($mail->Body));
                }
                $mail->send();
            }
            return true;
        } catch (Exception $e) {
            error_log('Mailer Error: ' . $mail->ErrorInfo);
            error_log(json_encode($e));
            return false;
        }
    } else {
        $headers = 'MIME-Version: 1.0' . "\r\n";
        $headers .= self::$html ? 'Content-type: text/html; charset=UTF-8' . "\r\n" : 'Content-type: text/plain; charset=UTF-8' . "\r\n";
        $headers .= 'From: ' . MAIL_FROM_ADDRESS . "\r\n" .
            'Reply-To: ' . REPLY_TO_ADDRESS . "\r\n" .
            'X-Mailer: PHP/' . phpversion();

        return mail(self::$recipient, self::$subject, self::$message, $headers);
    }
}

Zpracování e-mailových adres

Jedním z běžných úkolů při práci s e-maily je validace a normalizace e-mailových adres. Implementoval jsem metodu getEmailAddresses, která zplošťuje vnořená pole, normalizuje e-mailové adresy a filtruje neplatné adresy.

public static function getEmailAddresses(array $emails = []): string
{
    if (empty($emails)) {
        return 'FAIL';
    }

    $flattenedEmails = self::flattenArray($emails);

    $normalizedEmails = array_map(function ($email) {
        return strtolower(trim($email));
    }, $flattenedEmails);

    $validEmails = array_filter($normalizedEmails, function ($email) {
        return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
    });

    if (empty($validEmails)) {
        return 'FAIL';
    }

    return implode(';', $validEmails);
}

public static function flattenArray(array $array): array
{
    $result = [];
    array_walk_recursive($array, function ($a) use (&$result) {
        $result[] = $a;
    });
    return $result;
}

Zpracování dat pomocí anonymní funkce

Metoda flattenArray používá array_walk_recursive s anonymní funkcí pro zploštění víceúrovňového pole. Zde je, jak data procházejí touto funkcí:

Při zadaném vstupním poli:

$emails = [[], [], [[], []], []];

Iterační kroky

  1. První iterace:
    • $carry = [] (počáteční hodnota)
    • $item = []
    • is_array($item) je true, takže se provede array_merge($carry, $item):
      • array_merge([], []) vrátí []
    • $carry se stane []
  2. Druhá iterace:
    • $carry = []
    • $item = []
    • is_array($item) je true, takže se provede array_merge($carry, $item):
      • array_merge([], []) vrátí []
    • $carry zůstává []
  3. Třetí iterace:
    • $carry = []
    • $item = [[], []]
    • is_array($item) je true, takže se provede array_merge($carry, $item):
      • array_merge([], [[], []]) vrátí [[], []]
    • $carry se aktualizuje na [[], []]
  4. Čtvrtá iterace:
    • $carry = [[], []]
    • $item = []
    • is_array($item) je true, takže se provede array_merge($carry, $item):
      • array_merge([[], []], []) vrátí [[], []]
    • $carry zůstává [[], []]

Výsledek

Po dokončení iterací je $flattenedEmails:

return = [[], []]

Tento přístup efektivně zplošťuje strukturu vnořeného pole do jednorozměrného pole, které může být dále zpracováno.


Comments

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *