Kirim Email dengan PHP: mail() vs PHPMailer

Mengirim email adalah kebutuhan yang sangat umum di aplikasi web. Contohnya:

  • form kontak
  • email reset password
  • notifikasi pesanan
  • email verifikasi akun

Di PHP, ada dua pendekatan yang paling sering ditemui:

  1. memakai fungsi bawaan mail()
  2. memakai library seperti PHPMailer

Untuk belajar, kamu sebaiknya memahami keduanya. Tetapi untuk project sungguhan, PHPMailer + SMTP biasanya jauh lebih stabil.

Kenapa mail() Sering Membingungkan?

Di komputer local, banyak pemula menulis kode mail() lalu mengira semuanya benar karena fungsi tersebut mengembalikan true. Padahal emailnya tidak pernah benar-benar terkirim.

Itu terjadi karena:

  • server local belum punya mail server yang terkonfigurasi
  • header email kurang lengkap
  • provider email menolak email yang tidak lolos autentikasi

Karena itu, anggap mail() sebagai pengenalan konsep. Untuk penggunaan nyata, lebih aman memakai SMTP melalui PHPMailer.

1. Membuat Form Kontak Sederhana

Buat file contact.php:

<?php
$pesanSukses = '';
$pesanError = '';

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $nama = trim($_POST['nama'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $pesan = trim($_POST['pesan'] ?? '');

    if ($nama === '' || $email === '' || $pesan === '') {
        $pesanError = 'Semua field wajib diisi.';
    }
}
?>

<form method="POST">
    <label>Nama</label>
    <input type="text" name="nama" required>

    <label>Email</label>
    <input type="email" name="email" required>

    <label>Pesan</label>
    <textarea name="pesan" rows="5" required></textarea>

    <button type="submit">Kirim</button>
</form>

Sebelum email benar-benar dikirim, validasi inputnya dulu. Jangan langsung percaya isi $_POST.

2. Opsi Pertama: Mengirim dengan mail()

Contoh paling dasar:

<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $nama = trim($_POST['nama'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $pesan = trim($_POST['pesan'] ?? '');

    if ($nama !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) && $pesan !== '') {
        $kepada = '[email protected]';
        $subjek = 'Pesan Baru dari Form Kontak';

        $isi = "Nama: {$nama}\n";
        $isi .= "Email: {$email}\n\n";
        $isi .= "Pesan:\n{$pesan}";

        $headers = "From: [email protected]\r\n";
        $headers .= "Reply-To: {$email}\r\n";

        if (mail($kepada, $subjek, $isi, $headers)) {
            echo 'Email berhasil dikirim.';
        } else {
            echo 'Email gagal dikirim.';
        }
    }
}

Kode di atas berguna untuk memahami alur dasar:

  1. ambil data dari form
  2. susun subject dan isi email
  3. kirim ke alamat tujuan

Tetapi ada keterbatasan besar:

  • sulit debug kalau gagal
  • tidak nyaman untuk email HTML
  • bergantung penuh pada konfigurasi mail server

3. Opsi yang Direkomendasikan: PHPMailer + SMTP

Kalau kamu ingin hasil yang lebih konsisten, gunakan PHPMailer.

Install dulu package-nya:

composer require phpmailer/phpmailer

Lalu buat file kirim-email.php:

<?php
require __DIR__ . '/vendor/autoload.php';

use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\PHPMailer;

if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $nama = trim($_POST['nama'] ?? '');
    $email = trim($_POST['email'] ?? '');
    $pesan = trim($_POST['pesan'] ?? '');

    if ($nama === '' || !filter_var($email, FILTER_VALIDATE_EMAIL) || $pesan === '') {
        die('Input tidak valid.');
    }

    $mail = new PHPMailer(true);

    try {
        $mail->isSMTP();
        $mail->Host = 'smtp.gmail.com';
        $mail->SMTPAuth = true;
        $mail->Username = '[email protected]';
        $mail->Password = 'app-password';
        $mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port = 587;

        $mail->setFrom('[email protected]', 'Website Belajar PHP');
        $mail->addAddress('[email protected]', 'Admin');
        $mail->addReplyTo($email, $nama);

        $mail->isHTML(true);
        $mail->Subject = 'Pesan Baru dari Form Kontak';
        $mail->Body = "
            <h2>Pesan Baru</h2>
            <p><strong>Nama:</strong> " . htmlspecialchars($nama) . "</p>
            <p><strong>Email:</strong> " . htmlspecialchars($email) . "</p>
            <p><strong>Pesan:</strong><br>" . nl2br(htmlspecialchars($pesan)) . "</p>
        ";

        $mail->AltBody = "Nama: {$nama}\nEmail: {$email}\n\nPesan:\n{$pesan}";

        $mail->send();
        echo 'Email berhasil dikirim lewat SMTP.';
    } catch (Exception $e) {
        echo 'Email gagal dikirim. Error: ' . $mail->ErrorInfo;
    }
}

Kenapa SMTP Lebih Baik?

Dengan SMTP, kamu berbicara langsung ke server pengirim email yang jelas. Keuntungannya:

  • autentikasi lebih rapi
  • error lebih mudah dibaca
  • lebih mudah dipakai untuk email HTML
  • cocok untuk notifikasi aplikasi yang benar-benar dipakai user

4. Menyimpan Konfigurasi Email dengan Lebih Aman

Jangan hardcode username dan password SMTP langsung di source code production.

Contoh sederhana:

<?php
$smtpHost = $_ENV['MAIL_HOST'] ?? 'smtp.gmail.com';
$smtpPort = (int) ($_ENV['MAIL_PORT'] ?? 587);
$smtpUser = $_ENV['MAIL_USERNAME'] ?? '';
$smtpPass = $_ENV['MAIL_PASSWORD'] ?? '';

Nanti setelah belajar file konfigurasi, kamu bisa pindahkan nilai ini ke .env. Ini jauh lebih aman daripada menulis password langsung di file PHP.

5. Mengirim Email HTML

Kalau kamu ingin email lebih rapi, PHPMailer mendukung HTML:

<?php
$mail->isHTML(true);
$mail->Subject = 'Selamat Datang!';
$mail->Body = '
    <h1>Halo, Budi!</h1>
    <p>Akun kamu berhasil dibuat.</p>
    <p>Silakan login untuk mulai menggunakan aplikasi.</p>
';

Tetap buat AltBody untuk jaga-jaga kalau client email penerima tidak mendukung HTML.

6. Kapan Pakai mail() dan Kapan Pakai PHPMailer?

KebutuhanPilihan
Belajar konsep dasar pengiriman emailmail()
Project local sederhana untuk eksperimenmail() atau Mailpit/Mailhog
Form kontak sungguhanPHPMailer
Email reset password / notifikasi pentingPHPMailer
Email HTML, attachment, SMTP authPHPMailer

Kalau project kamu sudah mulai dipakai orang lain, PHPMailer hampir selalu lebih aman dipilih.

Error Umum

mail() mengembalikan sukses, tapi inbox kosong

Biasanya bukan karena kode PHP salah, tetapi karena server belum bisa mengirim email keluar atau email masuk ke spam.

SMTP Error: Could not authenticate

Penyebab paling umum:

  • username/password salah
  • belum memakai app password
  • provider email memblokir login biasa

Class "PHPMailer\PHPMailer\PHPMailer" not found

Biasanya package belum di-install atau vendor/autoload.php belum di-include.

Karakter aneh saat menampilkan email HTML

Pastikan encoding benar:

<?php
$mail->CharSet = 'UTF-8';

Pesan user tampil mentah di email HTML

Kalau isi form langsung dimasukkan ke HTML email tanpa htmlspecialchars(), user bisa menyisipkan HTML liar. Selalu escape data dari user.

Tips Praktis

  1. Validasi email dengan filter_var(..., FILTER_VALIDATE_EMAIL).
  2. Pakai htmlspecialchars() saat menampilkan input user ke email HTML.
  3. Simpan kredensial SMTP di konfigurasi, bukan di source code.
  4. Gunakan try-catch supaya error lebih mudah dibaca.
  5. Untuk local development, pertimbangkan mail catcher seperti Mailpit agar tidak benar-benar mengirim email ke inbox asli.

Bacaan Terkait