Fungsi surat PHP tidak menyelesaikan pengiriman email


477
<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com';
    $to = 'contact@yoursite.com';
    $subject = 'Customer Inquiry';
    $body = "From: $name\n E-Mail: $email\n Message:\n $message";

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $from)) {
            echo '<p>Your message has been sent!</p>';
        } else {
            echo '<p>Something went wrong, go back and try again!</p>';
        }
    }
?>

Saya sudah mencoba membuat formulir surat sederhana. Formulir itu sendiri ada di index.htmlhalaman saya , tetapi mengirimkan ke halaman terpisah "terima kasih atas kiriman Anda" thankyou.php, di mana kode PHP di atas tertanam. Kode dikirimkan dengan sempurna, tetapi tidak pernah mengirim email. Bagaimana saya bisa memperbaikinya?


2
adalah program Anda di komputer lokal atau siaran langsung
Tamil Selvan C

6
1. Anda yakin itu tidak masuk ke spam Anda? 2. apakah Anda telah mengkonfigurasi sendmail di komputer Anda?
Steven Moseley

itu pada live host itu tidak masuk ke spam saya .. saya tidak yakin apa yang Anda maksud dengan memiliki sendmail yang dikonfigurasi pada kotak saya jadi saya berasumsi tidak?
user3818620

coba kirim tanpa$from
Artem Ilchenko

Jawaban:


512

Meskipun ada bagian dari jawaban ini yang hanya berlaku untuk penggunaan mail()fungsi itu sendiri, banyak dari langkah pemecahan masalah ini dapat diterapkan ke sistem pengiriman PHP apa pun.

Ada berbagai alasan mengapa skrip Anda tampaknya tidak mengirim email. Sulit untuk mendiagnosis hal-hal ini kecuali ada kesalahan sintaksis yang jelas. Tanpa yang Anda perlu menjalankan melalui daftar periksa di bawah ini untuk menemukan potensi jebakan yang mungkin Anda temui.

Pastikan pelaporan kesalahan diaktifkan dan diatur untuk melaporkan semua kesalahan

Pelaporan kesalahan sangat penting untuk membasmi bug dalam kode Anda dan kesalahan umum yang ditemui PHP. Pelaporan kesalahan perlu diaktifkan untuk menerima kesalahan ini. Menempatkan kode berikut di bagian atas file PHP Anda (atau dalam file konfigurasi master) akan memungkinkan pelaporan kesalahan.

error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");

Lihat Bagaimana saya bisa mendapatkan pesan kesalahan yang berguna dalam PHP? - jawaban ini untuk detail lebih lanjut tentang ini.

Pastikan mail()fungsinya dipanggil

Ini mungkin tampak konyol tetapi kesalahan umum adalah lupa untuk benar-benar menempatkan mail()fungsi dalam kode Anda. Pastikan itu ada di sana dan tidak dikomentari.

Pastikan mail() fungsinya dipanggil dengan benar

bool mail (string $ to, string $ subject, string $ message [, string $ additional_headers [, string $ additional_parameters]])

Fungsi mail mengambil tiga parameter yang diperlukan dan opsional yang keempat dan kelima. Jika panggilan Anda kemail() tidak memiliki setidaknya tiga parameter itu akan gagal.

Jika panggilan Anda ke mail() tidak memiliki parameter yang benar dalam urutan yang benar, itu juga akan gagal.

Periksa log surat server

Server web Anda harus mencatat semua upaya untuk mengirim email melaluinya. Lokasi log ini akan bervariasi (Anda mungkin perlu bertanya kepada administrator server Anda di mana mereka berada) tetapi mereka biasanya dapat ditemukan di direktori root pengguna di bawah logs. Di dalamnya akan ada pesan kesalahan yang dilaporkan server, jika ada, terkait dengan upaya Anda untuk mengirim email.

Periksa kegagalan koneksi Port

Port block adalah masalah yang sangat umum yang dihadapi sebagian besar pengembang saat mengintegrasikan kode mereka untuk mengirim email menggunakan SMTP. Dan, ini dapat dengan mudah dilacak di server maillogs (lokasi server mail log dapat bervariasi dari server ke server, seperti dijelaskan di atas). Jika Anda menggunakan server hosting bersama, port 25 dan 587 tetap diblokir secara default. Blok ini sengaja dilakukan oleh penyedia hosting Anda. Ini berlaku bahkan untuk beberapa server khusus. Ketika port-port ini diblokir, cobalah untuk terhubung menggunakan port 2525. Jika Anda menemukan port itu juga diblokir, maka satu-satunya solusi adalah dengan menghubungi penyedia hosting Anda untuk membuka blokir port-port ini.

Sebagian besar penyedia hosting memblokir port email ini untuk melindungi jaringan mereka dari mengirim email spam apa pun.

Gunakan porta 25 atau 587 untuk koneksi plain / TLS dan port 465 untuk koneksi SSL. Untuk sebagian besar pengguna, disarankan untuk menggunakan port 587 untuk menghindari batas tingkat yang ditetapkan oleh beberapa penyedia hosting.

Jangan gunakan operator penekan kesalahan

Ketika operator penekan kesalahan @ didahului dengan ekspresi dalam PHP, pesan kesalahan apa pun yang mungkin dihasilkan oleh ekspresi itu akan diabaikan. Ada keadaan di mana menggunakan operator ini diperlukan tetapi mengirim surat bukan salah satunya.

Jika kode Anda berisi @mail(...)maka Anda mungkin menyembunyikan pesan kesalahan penting yang akan membantu Anda men-debug ini. Hapus @dan lihat apakah ada kesalahan yang dilaporkan.

Ini hanya disarankan ketika Anda memeriksa denganerror_get_last() tepat setelah kegagalan nyata.

Periksa nilai mail()pengembalian

The mail()Fungsi:

Kembali TRUEjika surat berhasil diterima untuk pengiriman, FALSEjika tidak. Penting untuk dicatat bahwa hanya karena surat diterima untuk pengiriman, BUKAN berarti surat itu benar-benar akan mencapai tujuan yang dimaksud.

Ini penting untuk diperhatikan karena:

  • Jika Anda menerima FALSEnilai kembali, Anda tahu kesalahannya terletak pada server Anda menerima email Anda. Ini mungkin bukan masalah pengkodean tetapi masalah konfigurasi server. Anda perlu berbicara dengan administrator sistem Anda untuk mengetahui mengapa hal ini terjadi.
  • Jika Anda menerima TRUEnilai kembali, itu tidak berarti email Anda pasti akan dikirim. Ini berarti email berhasil dikirim ke handler masing-masing di server oleh PHP. Masih ada lebih banyak titik kegagalan di luar kendali PHP yang dapat menyebabkan surel tidak terkirim.

Jadi FALSEakan membantu mengarahkan Anda ke arah yang benar sedangkan TRUEyang tidak selalu berarti email Anda berhasil dikirim. Ini penting untuk diperhatikan!

Pastikan penyedia hosting Anda memungkinkan Anda untuk mengirim email dan tidak membatasi pengiriman email

Banyak hosting bersama, terutama penyedia hosting web gratis, tidak mengizinkan email dikirim dari server mereka atau membatasi jumlah yang dapat dikirim selama periode waktu tertentu. Ini karena upaya mereka untuk membatasi spammer dari mengambil keuntungan dari layanan mereka yang lebih murah.

Jika menurut Anda host Anda memiliki batas email atau memblokir pengiriman email, periksa FAQ mereka untuk melihat apakah mereka mencantumkan batasan tersebut. Jika tidak, Anda mungkin perlu menjangkau dukungan mereka untuk memverifikasi jika ada batasan yang berlaku terkait pengiriman email.

Periksa folder spam; mencegah email ditandai sebagai spam

Seringkali, karena berbagai alasan, email yang dikirim melalui PHP (dan bahasa pemrograman sisi server lainnya) berakhir di folder spam penerima. Selalu periksa di sana sebelum memecahkan masalah kode Anda.

Agar email yang dikirim melalui PHP tidak terkirim ke folder spam penerima, ada berbagai hal yang dapat Anda lakukan, baik dalam kode PHP Anda maupun sebaliknya, untuk meminimalkan peluang email Anda ditandai sebagai spam. Kiat-kiat bagus dari Michiel de Mare meliputi:

  • Gunakan metode otentikasi email, seperti SPF , dan DKIM untuk membuktikan bahwa email Anda dan nama domain Anda menjadi satu, dan untuk mencegah spoofing nama domain Anda. Situs web SPF mencakup panduan untuk menghasilkan informasi DNS untuk situs Anda.
  • Periksa DNS balik Anda untuk memastikan alamat IP server surat Anda menunjuk ke nama domain yang Anda gunakan untuk mengirim email.
  • Pastikan alamat IP yang Anda gunakan tidak ada dalam daftar hitam
  • Pastikan alamat balasan adalah alamat yang ada dan valid.
  • Gunakan nama asli penerima yang lengkap di bidang Ke, bukan hanya alamat email (mis "John Smith" <john@blacksmiths-international.com>.).
  • Pantau akun penyalahgunaan Anda, seperti abuse@domainanda.com dan postmaster@domainanda.com. Itu berarti - pastikan bahwa akun-akun ini ada, baca apa yang dikirimkan kepada mereka, dan menindaklanjuti keluhan.
  • Akhirnya, membuatnya sangat mudah untuk berhenti berlangganan. Jika tidak, pengguna Anda akan berhenti berlangganan dengan menekan tombol spam , dan itu akan memengaruhi reputasi Anda.

Lihat Bagaimana Anda memastikan email yang Anda kirim secara terprogram tidak secara otomatis ditandai sebagai spam? untuk lebih lanjut tentang topik ini.

Pastikan semua header surat disediakan

Beberapa perangkat lunak spam akan menolak email jika tidak ada tajuk umum seperti "Dari" dan "Balas ke":

$headers = array("From: from@example.com",
    "Reply-To: replyto@example.com",
    "X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);

Pastikan header surat tidak memiliki kesalahan sintaksis

Header yang tidak valid sama buruknya dengan tidak memiliki header. Hanya satu karakter yang salah yang diperlukan untuk menggagalkan email Anda. Periksa ulang untuk memastikan sintaks Anda benar karena PHP tidak akan menangkap kesalahan ini untuk Anda.

$headers = array("From from@example.com", // missing colon
    "Reply To: replyto@example.com",      // missing hyphen
    "X-Mailer: "PHP"/" . PHP_VERSION      // bad quotes
);

Jangan gunakan From:pengirim palsu

Meskipun email harus memiliki pengirim Dari:, Anda tidak boleh hanya menggunakan nilai apa pun . Khususnya alamat pengirim yang dikotori oleh pengguna adalah cara yang pasti untuk membuat email diblokir:

$headers = array("From: $_POST[contactform_sender_email]"); // No!

Alasan: web atau server email Anda tidak masuk dalam daftar SPF / DKIM untuk berpura-pura bertanggung jawab atas alamat @hotmail atau @gmail. Bahkan dapat secara diam-diam mengirim surat dengan From:domain pengirim yang tidak dikonfigurasikan untuknya.

Pastikan nilai penerima sudah benar

Terkadang masalahnya sesederhana memiliki nilai yang salah untuk penerima email. Ini bisa jadi karena menggunakan variabel yang salah.

$to = 'user@example.com';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to

Cara lain untuk menguji ini adalah dengan mengkodekan nilai penerima ke mail()pemanggilan fungsi:

mail('user@example.com', $subject, $message, $headers); 

Ini dapat berlaku untuk semua mail()parameter.

Kirim ke banyak akun

Untuk membantu mengesampingkan masalah akun email, kirim email Anda ke beberapa akun email di penyedia email berbeda . Jika email Anda tidak sampai di akun Gmail pengguna, kirim email yang sama ke akun Yahoo, akun Hotmail, dan akun POP3 biasa (seperti akun email yang disediakan ISP Anda).

Jika email sampai di semua atau beberapa akun email lain, Anda tahu kode Anda mengirim email, tetapi kemungkinan penyedia akun email memblokirnya karena alasan tertentu. Jika email tidak sampai pada akun email apa pun, masalahnya lebih mungkin terkait dengan kode Anda.

Pastikan kode cocok dengan metode formulir

Jika Anda telah mengatur metode formulir Anda POST, pastikan Anda menggunakan $_POSTuntuk mencari nilai formulir Anda. Jika Anda telah menyetelnya ke GETatau tidak menyetelnya sama sekali, pastikan Anda menggunakan $_GETuntuk mencari nilai formulir Anda.

Pastikan actionnilai formulir Anda menunjuk ke lokasi yang benar

Pastikan actionatribut formulir Anda berisi nilai yang mengarah ke kode surat PHP Anda.

<form action="send_email.php" method="POST">

Pastikan host Web mendukung pengiriman email

Beberapa penyedia hosting web tidak mengizinkan atau mengaktifkan pengiriman email melalui server mereka. Alasannya mungkin berbeda, tetapi jika mereka telah menonaktifkan pengiriman surat, Anda harus menggunakan metode alternatif yang menggunakan pihak ketiga untuk mengirim email itu untuk Anda.

Email ke dukungan teknis mereka (setelah perjalanan ke dukungan online atau FAQ mereka) harus menjelaskan apakah kemampuan email tersedia di server Anda.

Pastikan localhostserver email dikonfigurasi

Jika Anda mengembangkan pada workstation lokal Anda menggunakan WAMP, MAMP, atau XAMPP, server email mungkin tidak diinstal pada workstation Anda. Tanpa satu, PHP tidak dapat mengirim email secara default.

Anda dapat mengatasinya dengan menginstal server email dasar. Untuk Windows Anda dapat menggunakan Mercury Mail gratis .

Anda juga dapat menggunakan SMTP untuk mengirim email Anda. Lihat jawaban hebat dari Vikas Dwivedi ini untuk mempelajari cara melakukan ini.

Aktifkan custom PHP mail.log

Selain file log MTA dan PHP, Anda dapat mengaktifkan pencatatan untuk mail()fungsi secara khusus. Itu tidak merekam interaksi SMTP lengkap, tetapi setidaknya parameter fungsi panggilan dan skrip doa.

ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);

Lihat http://php.net/manual/en/mail.configuration.php untuk detailnya. (Cara terbaik untuk mengaktifkan opsi ini di php.iniatau .user.iniatau .htaccessmungkin.)

Periksa dengan layanan pengujian surat

Ada berbagai layanan pengiriman dan pemeriksaan spam yang dapat Anda gunakan untuk menguji pengaturan MTA / server web Anda. Biasanya Anda mengirim penyelidikan surat ke: alamatnya, lalu dapatkan laporan pengiriman dan kegagalan atau analisis yang lebih nyata nanti:

Gunakan mailer lain

mail()Fungsi built-in PHP berguna dan seringkali menyelesaikan pekerjaan tetapi memiliki kekurangan . Untungnya ada alternatif yang menawarkan lebih banyak kekuatan dan fleksibilitas termasuk menangani banyak masalah yang diuraikan di atas:

Semuanya dapat dikombinasikan dengan server / penyedia layanan SMTP profesional. (Karena paket webhosting bersama 08/15 tipikal mengenai hit atau miss ketika datang ke pengaturan email / konfigurabilitas.)


11
Ditulis dengan baik, John. Saya hanya akan menambahkan satu hal lagi: Memeriksa log server surat dari server pengiriman surat (apakah itu host lokal atau jarak jauh), jika mungkin, sering dapat menjelaskan apa yang menyebabkan masalah. Log-log ini harus menunjukkan 1) apakah pesan diterima atau tidak dari skrip PHP oleh server email pengirim dan jika demikian, 2) apakah MX yang diterima menerima atau tidak pengiriman dari server email pengirim.
mti2935

@ mti2935 Itu sangat membantu saya terkejut saya melewatkannya. Saya pasti akan menambahkannya secepat itu. :)
John Conde

1
saya akan mulai dengan jangan gunakan mail(), itu melakukan pekerjaan yang buruk dan lebih sulit untuk men-debug daripada perpustakaan surat lain

1
situs web yang sama pada 000webhost mengirim email dengan sukses dan cepat di domain netai.net tetapi di situs88.net saya memiliki situs web yang sama dengan konsol yang saya kirim berhasil tetapi saya tidak menerima pesan apa pun. Juga di domain comuf.com saya mendapatkan kesalahan. (Situs web yang sama pada host yang sama hanya berfungsi pada domain netai.net, net16.net juga berfungsi)
Nicolas Papaconstantinou

1
pertanyaan saya ( stackoverflow.com/questions/44866673/… ) telah ditandai sebagai duplikat dari pertanyaan ini, tetapi saya masih belum dapat menemukannya. Ada saran?
Zachary Elkins

37

Tambahkan header surat pada fungsi surat:

$header = "From: noreply@example.com\r\n";
$header.= "MIME-Version: 1.0\r\n";
$header.= "Content-Type: text/html; charset=ISO-8859-1\r\n";
$header.= "X-Priority: 1\r\n";

$status = mail($to, $subject, $message, $header);

if($status)
{
    echo '<p>Your mail has been sent!</p>';
} else {
    echo '<p>Something went wrong. Please try again!</p>';
}

25
  1. Selalu coba kirim tajuk dalam fungsi surat.
  2. Jika Anda mengirim email melalui localhost maka lakukan pengaturan SMTP untuk mengirim email.
  3. Jika Anda mengirim email melalui server, maka periksa fitur pengiriman email diaktifkan di server Anda.

20

Jika Anda menggunakan konfigurasi SMTP untuk mengirim email Anda, coba gunakan PHPMailer sebagai gantinya. Anda dapat mengunduh perpustakaan dari https://github.com/PHPMailer/PHPMailer .

Saya membuat email saya mengirim dengan cara ini:

function send_mail($email, $recipient_name, $message='')
{
    require("phpmailer/class.phpmailer.php");

    $mail = new PHPMailer();

    $mail->CharSet = "utf-8";
    $mail->IsSMTP();                                      // Set mailer to use SMTP
    $mail->Host = "mail.example.com";  // Specify main and backup server
    $mail->SMTPAuth = true;     // Turn on SMTP authentication
    $mail->Username = "myusername";  // SMTP username
    $mail->Password = "p@ssw0rd"; // SMTP password

    $mail->From = "me@walalang.com";
    $mail->FromName = "System-Ad";
    $mail->AddAddress($email, $recipient_name);

    $mail->WordWrap = 50;                                 // Set word wrap to 50 characters
    $mail->IsHTML(true);                                  // Set email format to HTML (true) or plain text (false)

    $mail->Subject = "This is a Sampleenter code here Email";
    $mail->Body    = $message;
    $mail->AltBody = "This is the body in plain text for non-HTML mail clients";
    $mail->AddEmbeddedImage('images/logo.png', 'logo', 'logo.png');
    $mail->addAttachment('files/file.xlsx');

    if(!$mail->Send())
    {
       echo "Message could not be sent. <p>";
       echo "Mailer Error: " . $mail->ErrorInfo;
       exit;
    }

    echo "Message has been sent";
}

2
Saya juga harus menggunakan: require ("phpmailer / class.smtp.php");
Doug

15

Cukup tambahkan beberapa tajuk sebelum mengirim surat:

<?php 
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com'; 
$to = 'contact@yoursite.com'; 
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/html\r\n";
$headers .= 'From: from@example.com' . "\r\n" .
'Reply-To: reply@example.com' . "\r\n" .
'X-Mailer: PHP/' . phpversion();

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

Dan satu hal lagi. The mail()fungsi tidak bekerja di localhost. Unggah kode Anda ke server dan coba.


1
ini benar-benar membuat formulir mengirimkan - pertanyaan saya sekarang akan menjadi ... bagaimana saya menunjukkan pengguna mengetikkan email, sekarang saya telah menggantinya dengan header ...
user3818620

apakah itu akan mencegah email dari folder spam. Saya telah melihat jika kami mengirim email lebih dari 10 menggunakan metode ini yang Anda gunakan dalam kode Anda, gmail mengirim email ini ke spam.
jewelhuq

OP memiliki baris ini: $from = 'From: yoursite.com'; Yang tidak terlihat seperti alamat email lengkap yang valid, tidak ada bagian lokal. Anda telah mengganti header Dari dan menambahkan yang lain. Atau lebih tepatnya di $fromatas berlebihan dalam contoh Anda. Dan menjadi cacat mungkin adalah masalah awal OP.
Progrock

13

Ini bekerja untuk saya di 000webhost dengan melakukan hal berikut:

$headers  = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type: text/html; charset=iso-8859-1" . "\r\n";
$headers .= "From: ". $from. "\r\n";
$headers .= "Reply-To: ". $from. "\r\n";
$headers .= "X-Mailer: PHP/" . phpversion();
$headers .= "X-Priority: 1" . "\r\n";

Masukkan langsung alamat email saat mengirim email:

mail('email@gmail.com', $subject, $message, $headers)

Gunakan ''dan tidak "".

Kode ini berfungsi, tetapi email diterima dengan jeda setengah jam.


10

Sebagian besar mail()fungsi dinonaktifkan di hosting bersama. Pilihan yang lebih baik adalah menggunakan SMTP. Opsi terbaik adalah Gmail atau SendGrid.


SMTPconfig.php

<?php 
    $SmtpServer="smtp.*.*";
    $SmtpPort="2525"; //default
    $SmtpUser="***";
    $SmtpPass="***";
?>

SMTPmail.php

<?php
class SMTPClient
{

    function SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body)
    {

        $this->SmtpServer = $SmtpServer;
        $this->SmtpUser = base64_encode ($SmtpUser);
        $this->SmtpPass = base64_encode ($SmtpPass);
        $this->from = $from;
        $this->to = $to;
        $this->subject = $subject;
        $this->body = $body;

        if ($SmtpPort == "") 
        {
            $this->PortSMTP = 25;
        }
        else
        {
            $this->PortSMTP = $SmtpPort;
        }
    }

    function SendMail ()
    {
        $newLine = "\r\n";
        $headers = "MIME-Version: 1.0" . $newLine;  
        $headers .= "Content-type: text/html; charset=iso-8859-1" . $newLine;  

        if ($SMTPIN = fsockopen ($this->SmtpServer, $this->PortSMTP)) 
        {
            fputs ($SMTPIN, "EHLO ".$HTTP_HOST."\r\n"); 
            $talk["hello"] = fgets ( $SMTPIN, 1024 ); 
            fputs($SMTPIN, "auth login\r\n");
            $talk["res"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpUser."\r\n");
            $talk["user"]=fgets($SMTPIN,1024);
            fputs($SMTPIN, $this->SmtpPass."\r\n");
            $talk["pass"]=fgets($SMTPIN,256);
            fputs ($SMTPIN, "MAIL FROM: <".$this->from.">\r\n"); 
            $talk["From"] = fgets ( $SMTPIN, 1024 ); 
            fputs ($SMTPIN, "RCPT TO: <".$this->to.">\r\n"); 
            $talk["To"] = fgets ($SMTPIN, 1024); 
            fputs($SMTPIN, "DATA\r\n");
            $talk["data"]=fgets( $SMTPIN,1024 );
            fputs($SMTPIN, "To: <".$this->to.">\r\nFrom: <".$this->from.">\r\n".$headers."\n\nSubject:".$this->subject."\r\n\r\n\r\n".$this->body."\r\n.\r\n");
            $talk["send"]=fgets($SMTPIN,256);
            //CLOSE CONNECTION AND EXIT ... 
            fputs ($SMTPIN, "QUIT\r\n"); 
            fclose($SMTPIN); 
            // 
        } 
        return $talk;
    } 
}
?>

contact_email.php

<?php 
include('SMTPconfig.php');
include('SMTPmail.php');
if($_SERVER["REQUEST_METHOD"] == "POST")
{
    $to = "";
    $from = $_POST['email'];
    $subject = "Enquiry";
    $body = $_POST['name'].'</br>'.$_POST['companyName'].'</br>'.$_POST['tel'].'</br>'.'<hr />'.$_POST['message'];
    $SMTPMail = new SMTPClient ($SmtpServer, $SmtpPort, $SmtpUser, $SmtpPass, $from, $to, $subject, $body);
    $SMTPChat = $SMTPMail->SendMail();
}
?>

Apakah ide yang baik untuk menyimpan pengguna smtp dan kata sandi dalam plaintext di server?
Juri

@Juri mungkin tidak ... tuhan aku tidak tahu bagaimana cara mendapatkan fungsi surat untuk bekerja:. (

9

Jika Anda hanya menggunakan mail()fungsi ini, Anda harus menyelesaikan file konfigurasi.

Anda perlu membuka ekspansi surat, dan mengatur SMTP smtp_portdan sebagainya, dan yang paling penting, nama pengguna dan kata sandi Anda. Tanpa itu, surat tidak dapat dikirim. Anda juga dapat menggunakan PHPMailkelas untuk mengirim.


9

Coba dua hal ini secara terpisah dan bersama-sama:

  1. Hapus if($_POST['submit']){}
  2. hapus $from(hanya usus saya)

8

Saya pikir ini harus melakukan trik. Saya baru saja menambahkan if(issetdan menambahkan rangkaian ke variabel dalam tubuh untuk memisahkan PHP dari HTML.

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];
    $from = 'From: yoursite.com'; 
    $to = 'contact@yoursite.com'; 
    $subject = 'Customer Inquiry';
    $body = "From:" .$name."\r\n E-Mail:" .$email."\r\n Message:\r\n" .$message;

if (isset($_POST['submit'])) 
{
    if (mail ($to, $subject, $body, $from)) 
    { 
        echo '<p>Your message has been sent!</p>';
    } 
    else 
    { 
        echo '<p>Something went wrong, go back and try again!</p>'; 
    }
}

?>

8

Bagi siapa saja yang menemukan ini maju, saya tidak akan merekomendasikan menggunakan mail. Ada beberapa jawaban yang menyentuh ini, tetapi bukan mengapa .

mailFungsi PHP tidak hanya buram, sepenuhnya bergantung pada MTA apa pun yang Anda gunakan (yaitu Sendmail ) untuk melakukan pekerjaan. hanyamail akan memberi tahu Anda jika MTA gagal menerimanya (mis. Sendmail turun saat Anda mencoba mengirim). Ia tidak dapat memberi tahu Anda jika surat berhasil karena dibagikan. Dengan demikian (seperti rincian jawaban John Conde ), Anda sekarang dapat mengutak-atik log MTA dan berharap bahwa itu memberi tahu Anda cukup tentang kegagalan untuk memperbaikinya. Jika Anda menggunakan host bersama atau tidak memiliki akses ke log MTA, Anda kurang beruntung. Sayangnya, default untuk sebagian besar pemasangan vanilla untuk Linux menanganinya dengan cara ini.

Pustaka surat ( PHPMailer , Zend Framework 2+, dll.), Melakukan sesuatu yang sangat berbeda mail. Mereka membuka soket langsung ke server email penerima dan kemudian mengirim perintah email SMTP langsung ke soket itu. Dengan kata lain, kelas bertindak sebagai MTA sendiri (perhatikan bahwa Anda dapat memberi tahu perpustakaan untuk menggunakanmail akhirnya mengirim surat, tapi saya sangat menyarankan Anda tidak melakukan itu).

Ini berarti Anda kemudian dapat langsung melihat respons dari server penerima (di PHPMailer, misalnya, Anda dapat mengaktifkan hasil debug ). Tidak ada lagi menebak apakah email gagal dikirim atau mengapa.

Jika Anda menggunakan SMTP (mis. Anda menelepon isSMTP()), Anda bisa mendapatkan transkrip terperinci dari percakapan SMTP menggunakanSMTPDebug properti.

Tetapkan opsi ini dengan memasukkan baris seperti ini di skrip Anda:

$mail->SMTPDebug = 2;

Anda juga mendapatkan manfaat dari antarmuka yang lebih baik. Dengan mailAnda harus mengatur semua tajuk, lampiran, dll. Dengan perpustakaan, Anda memiliki fungsi khusus untuk melakukan itu. Ini juga berarti fungsi melakukan semua bagian yang rumit (seperti header).


6
$name = $_POST['name'];
$email = $_POST['email'];
$reciver = '/* Reciver Email address */';
if (filter_var($reciver, FILTER_VALIDATE_EMAIL)) {
    $subject = $name;
    // To send HTML mail, the Content-type header must be set.
    $headers = 'MIME-Version: 1.0' . "\r\n";
    $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
    $headers .= 'From:' . $email. "\r\n"; // Sender's Email
    //$headers .= 'Cc:' . $email. "\r\n"; // Carbon copy to Sender
    $template = '<div style="padding:50px; color:white;">Hello ,<br/>'
        . '<br/><br/>'
        . 'Name:' .$name.'<br/>'
        . 'Email:' .$email.'<br/>'
        . '<br/>'
        . '</div>';
    $sendmessage = "<div style=\"background-color:#7E7E7E; color:white;\">" . $template . "</div>";
    // Message lines should not exceed 70 characters (PHP rule), so wrap it.
    $sendmessage = wordwrap($sendmessage, 70);
    // Send mail by PHP Mail Function.
    mail($reciver, $subject, $sendmessage, $headers);
    echo "Your Query has been received, We will contact you soon.";
} else {
    echo "<span>* invalid email *</span>";
}

6

Anda dapat menggunakan email config oleh CodeIgniter . Misalnya, menggunakan SMTP (cara sederhana):

$config = Array(
        'protocol' => 'smtp',
        'smtp_host' => 'mail.domain.com', // Your SMTP host
        'smtp_port' => 26, // Default port for SMTP
        'smtp_user' => 'name@domain.com',
        'smtp_pass' => 'password',
        'mailtype' => 'html',
        'charset' => 'iso-8859-1',
        'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('name@domain.com', 'Title');
$this->email->to('emaildestination@domain.com');
$this->email->subject('Header');
$this->email->message($message);

if($this->email->send()) 
{
   // Conditional true
}

Ini bekerja untuk saya!


1
fsockopen () [function.fsockopen]: php_network_getaddresses: getaddrinfo gagal: Tidak ada host yang dikenal. - Jika saya menemukan kesalahan ini, lalu apa alasannya dan apa yang perlu dilakukan?
Choudhury Saadmaan Mahmid

1
"Bekerja untukku" hanyalah info anekdotal, tetapi tidak banyak penjelasan yang benar-benar. Kata sandi port dan smtp akan menyesatkan bagi sebagian besar pengguna.
mario

Apa itu "email konfigurasi" ? Apakah Anda punya referensi?
Peter Mortensen

4

Coba ini

if ($_POST['submit']) {
    $success= mail($to, $subject, $body, $from);
    if($success)
    { 
        echo '
        <p>Your message has been sent!</p>
        ';
    } else { 
        echo '
        <p>Something went wrong, go back and try again!</p>
        '; 
    }
}

4

Mungkin masalahnya adalah konfigurasi server email. Untuk menghindari masalah seperti ini atau Anda tidak perlu khawatir tentang masalah server surat, saya sarankan Anda menggunakan PHPMailer .

Ini adalah plugin yang memiliki semua yang diperlukan untuk mengirim email, dan satu-satunya hal yang harus Anda perhitungkan adalah mengaktifkan port SMTP (Port: 25 dan 465), diaktifkan.

require_once 'PHPMailer/PHPMailer.php';
require_once '/servicios/PHPMailer/SMTP.php';
require_once '/servicios/PHPMailer/Exception.php';

$mail = new \PHPMailer\PHPMailer\PHPMailer(true);
try {
    //Server settings
    $mail->SMTPDebug = 0;
    $mail->isSMTP();
    $mail->Host = 'smtp.gmail.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'correo@gmail.com';
    $mail->Password = 'contrasenia';
    $mail->SMTPSecure = 'ssl';
    $mail->Port = 465;

    // Recipients
    $mail->setFrom('correo@gmail.com', 'my name');
    $mail->addAddress('destination@correo.com');

    // Attachments
    $mail->addAttachment('optional file');         // Add files, is optional

    // Content
    $mail->isHTML(true);// Set email format to HTML
    $mail->Subject = utf8_decode("subject");
    $mail->Body    = utf8_decode("mail content");
    $mail->AltBody = '';
    $mail->send();
}
catch (Exception $e) {
    $error = $mail->ErrorInfo;
}

1
IANA telah mengganti port 465 dengan port 587. Ini adalah port pengiriman surat standar. Ketika klien email atau server keluar mengirimkan email untuk dialihkan oleh server surat yang tepat, ia harus selalu menggunakan port SMTP 587 sebagai port default. Lihat mailgun.com/blog/which-smtp-port-understanding-ports-25-465-587 . Saran bijak: Jangan buka port di komputer Anda jika Anda tidak sepenuhnya tahu apa yang Anda lakukan!
Harm

3

Pastikan Anda telah menginstal Sendmail di server Anda.

Jika Anda telah memeriksa kode Anda dan memverifikasi bahwa tidak ada yang salah di sana, buka / var / mail dan periksa apakah folder itu kosong.

Jika kosong, Anda harus melakukan:

sudo apt-get install sendmail

jika Anda berada di server Ubuntu.


Itu terlalu kasar untuk berguna. Hanya menginstal MTA jarang memungkinkan untuk melakukannya. Dan panduan setup sendmail / postfix / qmail lengkap akan menjadi off-topic di sini.
mario

Apakah komentar ini mengacu pada jawaban saya? Karena ini belum terjadi pada saya dan saya tidak menyelesaikannya dengan cara yang persis sama. Ada berbagai kemungkinan jawaban untuk pertanyaan, milik saya menjadi salah satu dari mereka setelah mencoba semua hal di atas di masa lalu, jawaban saya telah memecahkan masalah bagi saya, jadi saya menawarkannya di sini sebagai solusi potensial lain.
Daniel

Ya tentu. Itu salah satu dari banyak kemungkinan jawaban. Namun, itu masih cara untuk IMO dangkal. Menggeneralisasikannya menjadi "Anda memerlukan MTA" seperti ... - dan di sini ada beberapa panduan pengaturan yang terhubung ... mungkin lebih praktis.
mario

3

Pertama-tama, Anda mungkin memiliki terlalu banyak parameter untuk fungsi mail () ... Anda dapat memiliki maksimum lima, mail(to, subject, message, headers, parameters);

Sejauh $fromvariabel berjalan, yang seharusnya secara otomatis berasal dari hosting Anda jika Anda menggunakan Linux cPanel . Secara otomatis berasal dari nama pengguna dan alamat IP cPanel Anda.

$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = 'contact@yoursite.com';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";

Pastikan juga Anda memiliki urutan variabel yang benar dalam fungsi mail () Anda.

Dalam mail($to, $subject, $message, etc.)urutan itu, atau ada kemungkinan itu tidak berfungsi.


3

Jika Anda kesulitan mengirim email dengan PHP, pertimbangkan alternatif seperti PHPMailer atau SwiftMailer .

Saya biasanya menggunakan SwiftMailer setiap kali saya perlu mengirim email dengan PHP.


Penggunaan dasar:

require 'mail/swift_required.php';

$message = Swift_Message::newInstance()
    // The subject of your email
    ->setSubject('Jane Doe sends you a message')
    // The from address(es)
    ->setFrom(array('jane.doe@gmail.com' => 'Jane Doe'))
    // The to address(es)
    ->setTo(array('frank.stevens@gmail.com' => 'Frank Stevens'))
    // Here, you put the content of your email
    ->setBody('<h3>New message</h3><p>Here goes the rest of my message</p>', 'text/html');

if (Swift_Mailer::newInstance(Swift_MailTransport::newInstance())->send($message)) {
    echo json_encode([
        "status" => "OK",
        "message" => 'Your message has been sent!'
    ], JSON_PRETTY_PRINT);
} else {
    echo json_encode([
        "status" => "error",
        "message" => 'Oops! Something went wrong!'
    ], JSON_PRETTY_PRINT);
}

Lihat dokumentasi resmi untuk informasi lebih lanjut tentang cara menggunakan SwiftMailer.


3

Bagi mereka yang tidak ingin menggunakan mailer eksternal dan ingin mail () pada server Linux khusus.

Caranya, bagaimana surat PHP, dijelaskan php.inipada bagian ini[mail function] .

Parameter sendmail-pathmenggambarkan bagaimana sendmail dipanggil. Nilai defaultnya adalah sendmail -t -i, jadi jika Anda dapat bekerja sendmail -t -i < message.txtdi konsol Linux - Anda akan selesai. Anda juga dapat menambahkan mail.logke debug dan pastikan mail () benar-benar dipanggil.

MTA yang berbeda dapat diimplementasikan sendmail. Mereka hanya membuat tautan simbolis ke binari mereka dengan nama itu. Sebagai contoh, di Debian defaultnya adalah Postfix . Konfigurasikan MTA Anda untuk mengirim email dan mengujinya dari konsol dengan sendmail -v -t -i < message.txt. File message.txtharus berisi semua tajuk pesan dan isi, alamat tujuan untuk amplop akan diambil dari To:tajuk. Contoh:

From: myapp@example.com
To: mymail@example.com
Subject: Test mail via sendmail.

Text body.

Saya lebih suka menggunakan ssmtp sebagai MTA karena sederhana dan tidak perlu menjalankan daemon dengan port yang terbuka. ssmtp hanya cocok untuk mengirim surat dari localhost . Itu juga dapat mengirim email yang diautentikasi melalui akun Anda pada layanan surat publik. Instal ssmtp dan edit file konfigurasi /etc/ssmtp/ssmtp.conf. Untuk dapat juga menerima mail sistem lokal ke akun Unix (misalnya peringatan untuk melakukan root dari cron jobs), konfigurasikan/etc/ssmtp/revaliases file.

Ini adalah konfigurasi saya untuk akun saya di surat Yandex:

root=mymail@example.com
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
AuthUser=abcde@yandex.ru
AuthPass=password

2

Ini hanya akan memengaruhi segelintir kecil pengguna, tetapi saya ingin mendokumentasikannya untuk segelintir kecil itu. Anggota segelintir kecil ini menghabiskan 6 jam untuk memecahkan masalah naskah surat PHP yang berfungsi karena masalah ini.

Jika Anda pergi ke universitas yang menjalankan XAMPP dari www.AceITLab.com, Anda harus tahu apa yang profesor kami tidak memberi tahu kami: Firewall AceITLab (bukan firewall Windows) memblokir MercuryMail di XAMPP. Anda harus menggunakan klien email alternatif, pear bekerja untuk kami. Anda harus mengirim ke akun Gmail dengan pengaturan keamanan rendah.

Ya, saya tahu, ini sama sekali tidak berguna untuk email dunia nyata. Namun, dari apa yang saya lihat, pengaturan akademik dan dunia nyata sering memiliki sedikit kesamaan yang berharga.


Itu terlalu aneh, dan memang tidak akan membantu orang lain. Silakan gunakan tautan [hapus] di bawah jawaban Anda.
mario

Apa "pir" dalam konteks ini? Apakah maksud Anda PEAR , repositori perangkat lunak PHP? Atau sesuatu yang lain? Misalnya rekan ?
Peter Mortensen

Apakah Anda benar-benar berarti "kecil yang berharga" ? Apakah itu sesuatu yang diharapkan? Mengapa?
Peter Mortensen

1

Jika Anda menjalankan kode ini di server lokal (mis. Komputer Anda untuk tujuan pengembangan), kode itu tidak akan mengirim email ke penerima. Ini akan membuat .txtfile di folder bernamamailoutput .

Dalam hal ini jika Anda menggunakan layanan selang gratis, suka 000webhostatau hostinger, penyedia layanan tersebut menonaktifkanmail() fungsi untuk mencegah penggunaan spoofing email, spamming, dll. Saya lebih suka Anda menghubungi mereka untuk melihat apakah mereka mendukung fitur ini.

Jika Anda yakin bahwa penyedia layanan mendukung fungsi mail (), Anda dapat memeriksa manual PHP ini untuk referensi lebih lanjut,

Surat PHP ()

Untuk memeriksa cuaca layanan hosting Anda mendukung fungsi mail (), coba jalankan kode ini (ingat untuk mengubah alamat email penerima) :

<?php
    $to      = 'nobody@example.com';
    $subject = 'the subject';
    $message = 'hello';
    $headers = 'From: webmaster@example.com' . "\r\n" .
        'Reply-To: webmaster@example.com' . "\r\n" .
        'X-Mailer: PHP/' . phpversion();

    mail($to, $subject, $message, $headers);
?>

1

Instalasi Sendmail untuk Debian 10.0.0 ('Buster') ternyata sepele!

php.ini

[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)

Instal paket sendmail standar (memungkinkan 'kirim'):

su -                                        # Install as user 'root'
dpkg --list                                 # Is install necessary?
apt-get install sendmail sendmail-cf m4     # Note multiple package selection
sendmailconfig                              # Respond all 'Y' for new install

Perintah lain-lain yang bermanfaat:

which sendmail                              # /usr/sbin/sendmail
which sendmailconfig                        # /usr/sbin/sendmailconfig
man sendmail                                # Documentation
systemctl restart sendmail                  # As and when required

Verifikasi (kemampuan mengirim)

echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com

Di atas butuh sekitar 5 menit. Maka saya membuang 5 jam ... Jangan lupa untuk memeriksa folder spam Anda !


0

Ada beberapa kemungkinan:

  1. Anda menghadapi masalah server. Server tidak memiliki server surat apa pun. Jadi surel Anda tidak berfungsi, karena kode Anda baik-baik saja dan surel berfungsi dengan baik.

  2. Anda tidak mendapatkan nilai yang diposting. Coba kode Anda dengan nilai statis.

  3. Gunakan email SMTP untuk mengirim email ...


0

Anda dapat menggunakan libmail: http://lwest.free.fr/doc/php/lib/index.php3?page=mail&lang=en

include "libmail.php";
$m = new Mail(); // Create the mail
$m->From($_POST['form']);
$m->To($_POST['to']);
$m->Subject($_POST['subject']);
$m->Body($_POST['body']);
$m->Cc($_POST['cc']);
$m->Priority(4);
// Attach a file of type 'image/gif' to be displayed in the message if possible
$m->Attach("/home/leo/toto.gif", "image/gif", "inline");
$m->Send(); // Send the mail
echo "Mail was sent:"
echo $m->Get(); // Show the mail source

5
Penting untuk disebutkan: ini hanyalah mail()pembungkus fungsi. Hanya menambahkan konstruksi pesan dan beberapa tipuan.
mario

0

Anda dapat melihat kesalahan Anda dengan:

error_reporting(E_ALL);

Dan kode sampel saya adalah:

<?php
    use PHPMailer\PHPMailer\PHPMailer;
    require 'PHPMailer.php';
    require 'SMTP.php';
    require 'Exception.php';

    $name = $_POST['name'];
    $mailid = $_POST['mail'];
    $mail = new PHPMailer;
    $mail->IsSMTP();
    $mail->SMTPDebug = 0;                   // Set mailer to use SMTP
    $mail->Host = 'smtp.gmail.com';         // Specify main and backup server
    $mail->Port = 587;                      // Set the SMTP port
    $mail->SMTPAuth = true;                 // Enable SMTP authentication
    $mail->Username = 'someone@gmail.com';  // SMTP username
    $mail->Password = 'password';           // SMTP password
    $mail->SMTPSecure = 'tls';              // Enable encryption, 'ssl' also accepted

    $mail->From = 'someone@gmail.com';
    $mail->FromName = 'name';
    $mail->AddAddress($mailid, $name);       // Name is optional
    $mail->IsHTML(true);                     // Set email format to HTML
    $mail->Subject = 'Here is the subject';
    $mail->Body    = 'Here is your message' ;
    $mail->AltBody = 'This is the body in plain text for non-HTML mail clients';
    if (!$mail->Send()) {
       echo 'Message could not be sent.';
       echo 'Mailer Error: ' . $mail->ErrorInfo;
       exit;
    }
    echo 'Message has been sent';
?>

1
SMTPDebug = 0tidak membantu. Atau "kata sandi" biasa tidak akan berfungsi dengan GMail. Jawaban ini tidak banyak berkontribusi di sini.
mario

-2

Selama sistem sendmail Anda berfungsi, kode Anda harus dimodifikasi sebagai berikut:

<?php
    $name = $_POST['name'];
    $email = $_POST['email'];
    $message = $_POST['message'];

    $header ="
Content-Type: text/html; charset=UTF-8\r\n
MIME-Version: 1.0\r\n
From: \"$name\" <$email>\r\n
Reply-To: no-reply@yoursite.com\r\n
X-Mailer: yoursite.com mailer\r\n
";

    $to = '"Contact" <contact@yoursite.com>'; 
    $subject = 'Customer Inquiry';
    $body =<<<EOB
<!DOCTYPE html>
<html>
    <body>
        $message
    </body>
</html>
EOB;

    if ($_POST['submit']) {
        if (mail ($to, $subject, $body, $header) !== false) { 
            echo '<p>Your message has been sent!</p>';
        } else { 
            echo '<p>Something went wrong, go back and try again!</p>'; 
        }
    }
?>

Ini memungkinkan Anda mengirim email berbasis HTML.

Yang menarik:

  1. kami membuat string multilines header (setiap baris dipisahkan oleh \ r \ n);
  2. kami menambahkan tipe konten untuk menyatakan kami mengembalikan HTML sehingga Anda dapat membuat email yang lebih baik (Anda dapat menambahkan kode HTML yang Anda inginkan, termasuk CSS, ke pesan Anda seperti yang akan Anda lakukan di halaman HTML).

Catatan: <<<EOBsintaks memerlukan penanda EOB terakhir dimulai sebagai awal dari baris dan tidak memiliki spasi atau karakter apa pun setelah tanda titik koma.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.