Cara Kirim Email dengan PHP: mail(), PHPMailer, SMTP & API

Di artikel ini
Untuk kirim email dengan PHP ada tiga cara: fungsi bawaan mail(), library PHPMailer yang mengirim lewat SMTP, atau REST API layanan email. Untuk website dan aplikasi yang sudah dipakai pelanggan, PHPMailer dengan SMTP berautentikasi lebih bisa diandalkan, karena mail() hanya menyerahkan pesan ke server lokal tanpa jaminan email sampai.
Panduan ini memberi contoh script PHP kirim email yang bisa langsung dipakai: kirim notifikasi pesanan, form kontak, dan kode verifikasi lewat API. Ada juga tabel error yang paling sering muncul beserta cara memperbaikinya.
Tiga Cara Kirim Email dengan PHP
Ketiga cara di bawah sama-sama berjalan di PHP biasa, Laravel, CodeIgniter, maupun plugin WordPress. Bedanya ada di jalur pengiriman dan seberapa banyak kontrol yang Anda dapat.
| Metode | Cara kerja | Kelebihan | Kekurangan | Cocok untuk |
|---|---|---|---|---|
mail() | Menyerahkan pesan ke program sendmail di server hosting | Tanpa library, satu baris kode | Tanpa autentikasi SMTP, tidak ada laporan pengiriman, mudah masuk spam | Uji coba lokal, notifikasi internal |
| PHPMailer + SMTP | Login ke server SMTP lalu mengirim lewat koneksi terenkripsi | Error jelas, HTML + lampiran, bisa pakai layanan SMTP relay | Perlu Composer dan kredensial SMTP | Form kontak, notifikasi pesanan, email aplikasi |
| REST API | Mengirim request HTTP (JSON) ke layanan email | Cepat, tidak tergantung port SMTP, respons berisi ID pesan | Terikat format API satu layanan | OTP, email transaksional volume tinggi |
Cara Kirim Email dengan Fungsi mail() PHP
Fungsi mail() menerima alamat tujuan, subjek, isi pesan, dan header tambahan. Header From wajib ada; tanpa itu PHP menampilkan peringatan “sendmail_from” not set in php.ini or custom “From:” header missing.
<?php
$to = '[email protected]';
$subject = 'Pesanan Anda sudah kami terima';
$message = "Halo,rnrnTerima kasih, pesanan #1024 sudah kami terima.";
$headers = [
'From' => 'Toko Contoh <[email protected]>',
'Reply-To' => '[email protected]',
'Content-Type' => 'text/plain; charset=UTF-8',
];
if (mail($to, $subject, $message, $headers)) {
echo 'Diterima server untuk dikirim (belum tentu sampai).';
} else {
echo 'mail() gagal: cek konfigurasi sendmail di server.';
}Perhatikan dua catatan dari dokumentasi resmi PHP. Pertama, nilai true hanya berarti pesan diterima untuk dikirim, bukan sudah sampai ke kotak masuk penerima. Kedua, mail() tidak cocok untuk volume besar di dalam loop, karena fungsi ini membuka dan menutup koneksi untuk setiap email.
Di hosting bersama, email dari mail() juga sering masuk spam. Penyebabnya, pesan dikirim dari IP server yang dipakai banyak situs dan biasanya belum selaras dengan SPF dan DKIM domain Anda. Karena itu, pakai mail() untuk uji coba saja, lalu pindah ke SMTP sebelum website dipakai pelanggan.
Cara Kirim Email PHP dengan PHPMailer dan SMTP
PHPMailer adalah library PHP open source untuk mengirim email lewat SMTP, lengkap dengan dukungan HTML, lampiran, dan enkripsi TLS. Per November 2026 versi utamanya adalah 7. Ringkasnya, ada empat langkah:
- Install PHPMailer dengan Composer.
- Siapkan host, port, username, dan password SMTP.
- Tulis script kirim email dan simpan kredensial di environment variable.
- Uji kirim ke alamat Anda sendiri, lalu cek folder inbox dan spam.
Langkah 1: Install PHPMailer dengan Composer
Jalankan perintah berikut di folder proyek. Composer membuat folder vendor/ beserta file vendor/autoload.php yang akan Anda panggil di script.
composer require phpmailer/phpmailerLangkah 2: Siapkan kredensial SMTP
Anda bisa memakai SMTP dari hosting, Gmail, atau layanan SMTP relay. Contoh di artikel ini memakai SMTP Mailketing. Nilainya ada di kartu Konfigurasi SMTP pada dashboard setelah Anda menambahkan domain pengirim di menu Setup Domain → Tambah Domain dan memverifikasinya.
| Pengaturan | Nilai | Keterangan |
|---|---|---|
| Host | smtp.mailketing.id | Server SMTP Mailketing |
| Port | 587 | Dengan enkripsi TLS (STARTTLS), sesuai yang tertulis di dashboard |
| Enkripsi | PHPMailer::ENCRYPTION_STARTTLS | Konstanta PHPMailer untuk port 587 |
| Username & password | Dari dashboard | Klik ikon mata untuk melihat password |
| Alamat pengirim | Alamat di domain terverifikasi | Misalnya [email protected] |
Jika Anda memakai layanan lain yang meminta port 465, ganti enkripsinya menjadi PHPMailer::ENCRYPTION_SMTPS. Penjelasan perbedaan port ada di artikel port SMTP 25, 465, 587, dan 2525.
Langkah 3: Script PHP kirim email dengan PHPMailer
Simpan username dan password di environment variable (misalnya file .env yang tidak ikut ter-upload ke repositori), bukan langsung di kode.
<?php
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerSMTP;
use PHPMailerPHPMailerException;
require 'vendor/autoload.php';
$mail = new PHPMailer(true); // true = error dilempar sebagai Exception
try {
// Server SMTP (nilai dari kartu Konfigurasi SMTP di dashboard Mailketing)
$mail->isSMTP();
$mail->Host = 'smtp.mailketing.id';
$mail->SMTPAuth = true;
$mail->Username = getenv('SMTP_USER');
$mail->Password = getenv('SMTP_PASS');
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->CharSet = 'UTF-8';
// $mail->SMTPDebug = SMTP::DEBUG_SERVER; // aktifkan saat mencari penyebab error
// Pengirim harus memakai domain yang sudah diverifikasi
$mail->setFrom('[email protected]', 'Toko Contoh');
$mail->addAddress('[email protected]', 'Budi');
$mail->addReplyTo('[email protected]', 'CS Toko Contoh');
$mail->isHTML(true);
$mail->Subject = 'Pesanan #1024 sudah kami terima';
$mail->Body = '<p>Halo Budi,</p><p>Pesanan <b>#1024</b> sudah kami terima dan sedang diproses.</p>';
$mail->AltBody = "Halo Budi,nPesanan #1024 sudah kami terima dan sedang diproses.";
$mail->send();
echo 'Email terkirim ke server SMTP.';
} catch (Exception $e) {
echo "Email gagal dikirim. Error: {$mail->ErrorInfo}";
}Isi AltBody dengan versi teks biasa. Aplikasi email yang tidak menampilkan HTML akan memakai teks ini, dan filter spam juga lebih menyukai email yang punya dua versi.
Belum punya akun SMTP? Daftar Mailketing dan dapatkan 200 email credit gratis untuk menguji script di atas. Setelah itu biayanya mulai Rp0,6 per email, tanpa biaya bulanan.
Contoh Script PHP Kirim Email dari Form Kontak
Kesalahan yang sering terjadi pada form kontak adalah memasang email pengunjung sebagai alamat From. Gmail dan Yahoo akan memeriksa DMARC domain pengunjung itu, dan email dari server Anda bisa ditolak. Cara yang benar: kirim dari alamat di domain Anda sendiri, lalu taruh email pengunjung di Reply-To.
<?php
use PHPMailerPHPMailerPHPMailer;
use PHPMailerPHPMailerException;
require 'vendor/autoload.php';
$nama = trim($_POST['nama'] ?? '');
$email = filter_var($_POST['email'] ?? '', FILTER_VALIDATE_EMAIL);
$pesan = trim($_POST['pesan'] ?? '');
if ($nama === '' || !$email || $pesan === '') {
http_response_code(422);
exit('Nama, email, dan pesan wajib diisi dengan benar.');
}
$mail = new PHPMailer(true);
try {
$mail->isSMTP();
$mail->Host = 'smtp.mailketing.id';
$mail->SMTPAuth = true;
$mail->Username = getenv('SMTP_USER');
$mail->Password = getenv('SMTP_PASS');
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->CharSet = 'UTF-8';
$mail->setFrom('[email protected]', 'Form Kontak Website'); // domain Anda sendiri
$mail->addAddress('[email protected]'); // kotak masuk tim
$mail->addReplyTo($email, $nama); // balasan ke pengunjung
$mail->Subject = 'Pesan baru dari ' . $nama;
$mail->Body = "Nama: {$nama}nEmail: {$email}nn{$pesan}";
$mail->send();
echo 'Terima kasih, pesan Anda sudah terkirim.';
} catch (Exception $e) {
error_log('Form kontak gagal: ' . $mail->ErrorInfo);
http_response_code(500);
echo 'Maaf, pesan belum terkirim. Silakan coba lagi.';
}Script ini juga memvalidasi input dengan filter_var() dan mencatat error ke log server, bukan ke layar pengunjung. Untuk proyek Laravel, konfigurasinya cukup di file .env; lihat panduan SMTP untuk Laravel.
Alternatif: Kirim Email dari PHP lewat REST API
Jika server Anda memblokir port SMTP keluar, atau Anda butuh respons cepat untuk OTP, kirim email lewat HTTP. Contoh berikut memanggil endpoint POST /send di API v2 Mailketing dengan cURL. Token API ada di menu Integrasi → Email Application API.
<?php
$payload = [
'from_name' => 'Toko Contoh',
'from_email' => '[email protected]', // domain terverifikasi
'recipient' => '[email protected]',
'subject' => 'Kode verifikasi Anda',
'content' => '<html><body><p>Kode verifikasi Anda: <b>482913</b></p></body></html>',
];
$ch = curl_init('https://api.mailketing.co.id/api/v2/send');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Api-Token: ' . getenv('MAILKETING_API_TOKEN'),
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_TIMEOUT => 15,
]);
$response = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$data = json_decode($response, true);
echo $status === 200 ? 'Terkirim, message_id: ' . ($data['data']['message_id'] ?? '-') : "Gagal ($status): $response";Jika berhasil, respons berisi data.message_id yang dibuat otomatis oleh Mailketing. Simpan ID ini untuk melacak status email. Field lengkap dan kode error ada di dokumentasi kirim email via API serta panduan API Mailketing untuk developer.
Error Kirim Email PHP yang Sering Muncul
Saat debugging, aktifkan $mail->SMTPDebug = SMTP::DEBUG_SERVER; agar percakapan dengan server SMTP tampil lengkap. Matikan lagi setelah masalah selesai.
| Pesan error | Penyebab umum | Solusi |
|---|---|---|
SMTP connect() failed | Host salah, atau port keluar diblokir hosting/firewall | Cek ejaan host, coba port lain yang didukung penyedia, tanyakan ke hosting apakah port 587 terbuka |
SMTP Error: Could not authenticate. | Username/password salah atau tertukar | Salin ulang kredensial dari dashboard; untuk Gmail gunakan App Password |
mail() mengembalikan false | Sendmail tidak terpasang atau dinonaktifkan hosting | Pindah ke PHPMailer + SMTP |
| Berhasil terkirim tapi masuk spam | SPF, DKIM, atau DMARC domain belum diatur; alamat From bukan domain sendiri | Verifikasi domain pengirim dan pakai alamat di domain itu |
| API v2 membalas 403 Unknown sender domain | Domain from_email belum diverifikasi | Tambahkan dan verifikasi domain di dashboard |
Untuk error berkode 550, baca arti kode error SMTP 550 dan cara mengatasinya.
Kapan Pakai SMTP, Kapan Pakai API?
Pakai SMTP bila aplikasi atau plugin Anda sudah punya pengaturan SMTP, misalnya form WordPress, CMS, atau framework. Anda cukup mengganti host dan kredensial tanpa menulis ulang kode. Pakai API bila Anda menulis kode sendiri dan butuh kontrol lebih, seperti menyimpan ID pesan, mengirim OTP secepat mungkin, atau menghindari port SMTP yang diblokir. Perbandingan lengkapnya ada di Email API vs SMTP, dan langkah integrasinya di cara integrasi SMTP API.
Jika aplikasi Anda mengirim email ke banyak penerima, jangan memanggil mail() di dalam loop. Kirim lewat SMTP relay atau API dengan jeda yang sesuai batas kecepatan layanan. Penjelasannya ada di cara kerja rate limiting email API.
Sumber
- PHP Manual: mail() (return value, catatan volume besar, header From)
- PHPMailer di GitHub (instalasi Composer, contoh SMTP, konstanta enkripsi)
- Dokumentasi API Mailketing v2 (endpoint POST /send)
Pertanyaan yang Sering Diajukan
Apakah PHP bisa kirim email tanpa SMTP?
Bisa, dengan fungsi mail() yang memakai sendmail di server. Namun email jenis ini tidak berautentikasi, sehingga lebih mudah masuk spam dan tidak memberi laporan apakah email benar-benar sampai.
Kenapa mail() mengembalikan true tapi email tidak sampai?
Karena true hanya berarti pesan diterima server lokal untuk dikirim. Email bisa ditolak atau disaring di tengah jalan oleh server penerima, terutama jika domain pengirim belum punya SPF dan DKIM.
Bagaimana kirim email dengan PHP pakai Gmail?
Gunakan PHPMailer dengan host smtp.gmail.com, port 587 (STARTTLS), dan App Password sebagai password. Gmail punya batas kirim harian, jadi cara ini cocok untuk volume kecil. Langkah lengkapnya ada di panduan SMTP Gmail.
Bagaimana kirim email ke banyak penerima dengan PHP?
Jangan memakai satu email dengan ratusan alamat di kolom To. Kirim satu email per penerima lewat PHPMailer (aktifkan SMTPKeepAlive agar koneksi tidak dibuka ulang) atau lewat API, dengan jeda sesuai batas layanan.
Berapa biaya kirim email dari PHP pakai Mailketing?
Mulai Rp0,6 per email, bayar sesuai pemakaian tanpa biaya bulanan. Akun baru mendapat 200 email credit gratis untuk uji coba, baik lewat SMTP maupun API.
Siap memindahkan email website dari mail() ke SMTP yang berautentikasi? Coba Mailketing gratis, verifikasi domain Anda, lalu tempel host smtp.mailketing.id ke script PHPMailer di atas. Untuk kebutuhan integrasi aplikasi, lihat juga layanan SMTP API Mailketing.
Coba Mailketing gratis
Kirim email marketing, transaksional, dan OTP mulai Rp0,6/email — bayar sesuai pemakaian, tanpa biaya bulanan.
