{
    "slug": "php_mail",
    "term": "PHP Mail & SMTP",
    "category": "php",
    "difficulty": "beginner",
    "short": "Sending email from PHP using mail(), SMTP libraries like PHPMailer or Symfony Mailer, or transactional email APIs — with critical configuration for deliverability, security, and reliability.",
    "long": "PHP's built-in mail() function is a thin wrapper around the server's sendmail binary. It works on correctly configured servers but has no SMTP authentication, no TLS support, no error handling beyond a boolean return, and no queue — if the mail server is unavailable, the email is silently lost. For production, PHPMailer or Symfony Mailer send via authenticated SMTP with TLS, provide proper error exceptions, and support HTML email with embedded images. Transactional email APIs (Mailgun, SendGrid, Amazon SES, Postmark) provide delivery tracking, bounce handling, and high deliverability without managing an SMTP server. Deliverability requires three DNS records: SPF (which servers may send on your behalf), DKIM (cryptographic signature proving origin), and DMARC (policy for failed SPF/DKIM). Missing these records causes emails to land in spam or be rejected silently.",
    "aliases": [
        "mail()",
        "PHPMailer",
        "SMTP PHP",
        "Symfony Mailer",
        "email PHP",
        "sendmail PHP"
    ],
    "tags": [
        "email",
        "php",
        "smtp",
        "phpmailer",
        "deliverability",
        "spf",
        "dkim"
    ],
    "misconception": "If mail() returns true the email was delivered. mail() returns true if the message was accepted by the local mail transfer agent — not if it was delivered to the recipient. The MTA may queue it, the recipient server may reject it, or it may land in spam days later with no notification to PHP. PHPMailer with SMTP and exceptions provides actual delivery confirmation to the sending server; for end-to-end delivery tracking, a transactional API with webhooks is required.",
    "why_it_matters": "Email is a critical communication channel for most PHP applications — account verification, password resets, order confirmations, and notifications. Using mail() without SPF/DKIM records causes verification emails to land in spam, blocking user registration funnels. Sending from a shared hosting IP with no authentication causes emails to be rejected entirely. PHPMailer with a reputable SMTP service and correct DNS records is a two-hour setup that prevents months of deliverability problems.",
    "common_mistakes": [
        "Using mail() in production without SPF, DKIM, and DMARC DNS records — emails go to spam or are rejected.",
        "Not using a queue for email sending — synchronous email blocks the HTTP response and fails silently if the SMTP server is slow.",
        "Not validating email addresses with filter_var($email, FILTER_VALIDATE_EMAIL) before sending.",
        "Exposing SMTP credentials in version-controlled config files — always use environment variables for SMTP passwords and API keys."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "ssti",
        "apc_apcu",
        "cwe"
    ],
    "prerequisites": [],
    "refs": [
        "https://github.com/PHPMailer/PHPMailer",
        "https://www.php.net/manual/en/function.mail.php"
    ],
    "bad_code": "// mail() — no error handling, no TLS, poor deliverability\n$sent = mail(\n    $_POST['email'],  // unvalidated\n    'Welcome',\n    'Thanks for signing up',\n    'From: noreply@example.com' // likely to be spam\n);\n// Returns true even if email never delivered",
    "good_code": "// PHPMailer with SMTP + TLS\nuse PHPMailer\\PHPMailer\\PHPMailer;\nuse PHPMailer\\PHPMailer\\Exception;\n\n$mail = new PHPMailer(true); // true = throw exceptions\ntry {\n    $mail->isSMTP();\n    $mail->Host       = $_ENV['SMTP_HOST'];\n    $mail->SMTPAuth   = true;\n    $mail->Username   = $_ENV['SMTP_USER'];\n    $mail->Password   = $_ENV['SMTP_PASS'];\n    $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;\n    $mail->Port       = 587;\n    $mail->setFrom('noreply@example.com', 'My App');\n    $mail->addAddress(filter_var($email, FILTER_VALIDATE_EMAIL));\n    $mail->Subject = 'Welcome';\n    $mail->Body    = 'Thanks for signing up';\n    $mail->send();\n} catch (Exception $e) {\n    logger()->error('Mail failed: ' . $e->getMessage());\n}",
    "quick_fix": "Replace mail() with PHPMailer using SMTP + TLS, or use a transactional API (Mailgun/SendGrid). Add SPF, DKIM, DMARC DNS records. Queue email sending with Laravel Queue or similar",
    "severity": "medium",
    "effort": "low",
    "created": "2026-03-23",
    "updated": "2026-04-04",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/php_mail",
        "html_url": "https://codeclaritylab.com/glossary/php_mail",
        "json_url": "https://codeclaritylab.com/glossary/php_mail.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[PHP Mail & SMTP](https://codeclaritylab.com/glossary/php_mail) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/php_mail"
            }
        }
    }
}