PHP posta işlevi e-posta gönderimini tamamlamıyor
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$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>';
}
}
?>
Basit bir posta formu oluşturmayı denedim. Formun kendisi sayfamda index.html
, ancak thankyou.php
yukarıdaki PHP kodunun gömülü olduğu ayrı bir "gönderdiğiniz için teşekkür ederiz" sayfasına gönderiliyor . Kod mükemmel bir şekilde gönderilir, ancak asla bir e-posta göndermez. Bunu nasıl düzeltebilirim?
Yanıtlar
Bu cevabın yalnızca mail()
işlevin kullanımı için geçerli olan bazı bölümleri olsa da, bu sorun giderme adımlarının çoğu herhangi bir PHP posta sistemine uygulanabilir.
Komut dosyanızın e-posta göndermiyor gibi görünmesinin çeşitli nedenleri vardır. Açık bir sözdizimi hatası olmadıkça bu şeyleri teşhis etmek zordur. Bunlardan biri olmadan, karşılaşabileceğiniz olası tuzakları bulmak için aşağıdaki kontrol listesini gözden geçirmeniz gerekir.
Hata raporlamanın etkinleştirildiğinden ve tüm hataları rapor edecek şekilde ayarlandığından emin olun
Hata raporlama, kodunuzdaki hataları ve PHP'nin karşılaştığı genel hataları ortadan kaldırmak için çok önemlidir. Bu hataları almak için hata raporlama etkinleştirilmelidir. Aşağıdaki kodu PHP dosyalarınızın en üstüne (veya bir ana yapılandırma dosyasına) yerleştirmek hata raporlamayı etkinleştirir.
error_reporting(-1);
ini_set('display_errors', 'On');
set_error_handler("var_dump");
Bkz PHP yararlı hata iletileri alabilirim? - bununla ilgili daha fazla ayrıntı için bu cevap .
mail()
İşlevin çağrıldığından emin olun
Aptalca görünebilir, ancak yaygın bir hata, mail()
işlevi kodunuza gerçekten yerleştirmeyi unutmaktır . Orada olduğundan ve yorum yapılmadığından emin olun.
Emin olun mail()
fonksiyonun doğru denir
bool mail (dize $to , string $konu, dize $message [, string $ek_başlıklar [, dize $ ek_parametreler]])
Posta işlevi, üç gerekli parametreyi ve isteğe bağlı olarak dördüncü ve beşinci bir parametre alır. Çağrınızın mail()
en az üç parametresi yoksa başarısız olur.
Çağrınız mail()
doğru sırayla doğru parametrelere sahip değilse, aynı zamanda başarısız olacaktır.
Sunucunun posta günlüklerini kontrol edin
Web sunucunuz, üzerinden e-posta göndermek için tüm girişimleri günlüğe kaydetmelidir. Bu günlüklerin konumu değişebilir (sunucu yöneticinize nerede bulunduklarını sormanız gerekebilir), ancak bunlar genellikle altında bir kullanıcının kök dizininde bulunabilir logs
. İçeride, e-posta gönderme girişimlerinizle ilgili varsa, sunucunun bildirdiği hata mesajları olacaktır.
Bağlantı noktası bağlantı hatasını kontrol edin
Bağlantı noktası bloğu, çoğu geliştiricinin SMTP kullanarak e-posta göndermek için kodunu entegre ederken karşılaştığı çok yaygın bir sorundur. Ve bu, sunucu posta günlüklerinde kolayca izlenebilir (posta günlüğü sunucusunun konumu, yukarıda açıklandığı gibi, sunucudan sunucuya değişebilir). Paylaşılan bir barındırma sunucusundaysanız, 25 ve 587 numaralı bağlantı noktaları varsayılan olarak engellenmiş olarak kalır. Bu engelleme, barındırma sağlayıcınız tarafından bilerek yapılmıştır. Bu, bazı özel sunucular için bile geçerlidir. Bu bağlantı noktaları engellendiğinde, 2525 numaralı bağlantı noktasını kullanarak bağlanmayı deneyin. Bu bağlantı noktasının da engellendiğini görürseniz, tek çözüm bu bağlantı noktalarının engelini kaldırmak için barındırma sağlayıcınızla iletişime geçmektir.
Barındırma sağlayıcılarının çoğu, ağlarını herhangi bir spam e-posta göndermekten korumak için bu e-posta bağlantı noktalarını engeller.
Düz / TLS bağlantıları için 25 veya 587 numaralı bağlantı noktalarını ve SSL bağlantıları için 465 numaralı bağlantı noktalarını kullanın. Çoğu kullanıcı için, bazı barındırma sağlayıcıları tarafından belirlenen hız sınırlarından kaçınmak için 587 numaralı bağlantı noktasının kullanılması önerilir.
Hata bastırma operatörünü kullanmayın
Ne zaman hata bastırma operatörü @
PHP'de bir ifadesi önüne edilir, bu ifadesinin ürettiği olabilecek hata iletileri dikkate alınmaz. Bu operatörü kullanmanın gerekli olduğu durumlar vardır, ancak posta göndermek bunlardan biri değildir .
Kodunuz içeriyorsa @mail(...)
, bu hatayı gidermenize yardımcı olacak önemli hata mesajlarını saklıyor olabilirsiniz. Öğesini kaldırın @
ve herhangi bir hata bildirilip bildirilmediğine bakın.
Sadece somut arızalar için hemen sonra kontrolerror_get_last()
ettiğinizde tavsiye edilir .
mail()
Dönüş değerini kontrol edin
mail()
fonksiyon:
Aksi
TRUE
takdirde, posta teslim için başarıyla kabul edildiyse iade edilirFALSE
. Sadece postanın teslimat için kabul edilmiş olmasından dolayı, postanın gerçekten istenilen hedefe ulaşacağı anlamına gelmediğine dikkat etmek önemlidir.
Bunu not etmek önemlidir çünkü:
- Bir
FALSE
dönüş değeri alırsanız, hatanın sunucunuzun postanızı kabul etmesinden kaynaklandığını bilirsiniz. Bu muhtemelen bir kodlama sorunu değil, bir sunucu yapılandırma sorunu. Bunun neden olduğunu öğrenmek için sistem yöneticinizle konuşmanız gerekir. - Bir
TRUE
dönüş değeri alırsanız, bu e-postanızın kesinlikle gönderileceği anlamına gelmez. Bu sadece e-postanın sunucudaki ilgili işleyicisine PHP tarafından başarıyla gönderildiği anlamına gelir. E-postanın gönderilmemesine neden olabilecek PHP'nin kontrolü dışında hala daha fazla hata noktası vardır.
Yani FALSE
oysa doğru yönde bir işaret yardımcı olacaktır TRUE
gelmez değil mutlaka e-posta başarıyla gönderildi anlamına gelir. Bunu not etmek önemlidir!
Barındırma sağlayıcınızın e-posta göndermenize izin verdiğinden ve posta göndermeyi sınırlamadığından emin olun
Birçok paylaşılan web barındırıcısı, özellikle ücretsiz web barındırma sağlayıcıları, sunucularından e-postaların gönderilmesine izin vermez veya belirli bir süre içinde gönderilebilecek miktarı sınırlar. Bunun nedeni, spam gönderenlerin daha ucuz hizmetlerinden yararlanmasını sınırlama çabalarıdır.
Barındırıcınızın e-posta sınırlaması olduğunu veya e-posta gönderilmesini engellediğini düşünüyorsanız, bu tür sınırlamaları listeleyip listelemediklerini görmek için SSS'lerini kontrol edin. Aksi takdirde, e-postaların gönderilmesiyle ilgili herhangi bir kısıtlama olup olmadığını doğrulamak için onların desteğine ulaşmanız gerekebilir.
Spam klasörlerini kontrol edin; e-postaların spam olarak işaretlenmesini önlemek
Çoğu zaman, çeşitli nedenlerle, PHP (ve diğer sunucu tarafı programlama dilleri) aracılığıyla gönderilen e-postalar bir alıcının spam klasöründe son bulur. Kodunuzda sorun gidermeden önce daima orayı kontrol edin.
PHP aracılığıyla gönderilen postaların bir alıcının spam klasörüne gönderilmesini önlemek için, hem PHP kodunuzda hem de e-postalarınızın istenmeyen posta olarak işaretlenme olasılığını en aza indirmek için yapabileceğiniz çeşitli şeyler vardır. Michiel de Mare'den iyi ipuçları şunları içerir:
- E- postalarınızın ve alan adınızın birbirine ait olduğunu kanıtlamak ve alan adınızın sahteciliğini önlemek için SPF ve DKIM gibi e-posta kimlik doğrulama yöntemlerini kullanın . SPF web sitesi, siteniz için DNS bilgilerini oluşturmak için bir sihirbaz içerir.
- Posta sunucunuzun IP adresinin posta göndermek için kullandığınız alan adını gösterdiğinden emin olmak için ters DNS'nizi kontrol edin .
- Kullandığınız IP adresinin kara listede olmadığından emin olun
- Yanıt adresinin geçerli ve mevcut bir adres olduğundan emin olun.
- Alıcı alanında, yalnızca e-posta adresini değil (örneğin
"John Smith" <[email protected]>
) alıcının tam, gerçek adını kullanın .- Abuse@alanınız.com ve [email protected] gibi kötüye kullanım hesaplarınızı izleyin. Bunun anlamı - bu hesapların var olduğundan emin olun, onlara gönderilenleri okuyun ve şikayetler üzerine harekete geçin.
- Son olarak, abonelikten çıkmayı gerçekten kolaylaştırın. Aksi takdirde, kullanıcılarınız spam düğmesine basarak abonelikten çıkacak ve bu itibarınızı etkileyecektir.
Bkz. Programlı olarak gönderdiğiniz e-postanın otomatik olarak spam olarak işaretlenmediğinden nasıl emin oluyorsunuz? bu konu hakkında daha fazlası için.
Tüm posta başlıklarının sağlandığından emin olun
Bazı spam yazılımları, "Kimden" ve "Yanıtla" gibi ortak üstbilgiler eksikse postayı reddeder:
$headers = array("From: [email protected]",
"Reply-To: [email protected]",
"X-Mailer: PHP/" . PHP_VERSION
);
$headers = implode("\r\n", $headers);
mail($to, $subject, $message, $headers);
Posta üstbilgilerinde sözdizimi hatası olmadığından emin olun
Geçersiz başlıklar, başlıkların olmaması kadar kötüdür. E-postanızı raydan çıkarmak için tek yapmanız gereken bir yanlış karakter olabilir. Tekrar kontrol edin PHP şekliyle sözdizimi doğru olduğundan emin olmak için değil sizin için bu hataları yakalamak.
$headers = array("From [email protected]", // missing colon
"Reply To: [email protected]", // missing hyphen
"X-Mailer: "PHP"/" . PHP_VERSION // bad quotes
);
Sahte From:
gönderen kullanmayın
Postanın bir Gönderen: göndereni olması gerekirken, herhangi bir değer kullanamazsınız . Özellikle kullanıcı tarafından sağlanan gönderen adresleri, postaların engellenmesi için kesin bir yoldur:
$headers = array("From: $_POST[contactform_sender_email]"); // No!
Nedeni: Web veya gönderen posta sunucunuz, @ hotmail veya @gmail adreslerinden sorumluymuş gibi davranmak için SPF / DKIM beyaz listeye eklenmemiş. From:
Yapılandırılmadığı gönderici etki alanlarına sahip postaları bile sessizce bırakabilir .
Alıcı değerinin doğru olduğundan emin olun
Bazen sorun, e-postanın alıcısı için yanlış bir değere sahip olmak kadar basittir. Bunun nedeni yanlış bir değişken kullanılması olabilir.
$to = '[email protected]';
// other variables ....
mail($recipient, $subject, $message, $headers); // $recipient should be $to
Bunu test etmenin başka bir yolu, alıcı değerini mail()
işlev çağrısına sabit kodlamaktır :
mail('[email protected]', $subject, $message, $headers);
Bu, tüm mail()
parametreler için geçerli olabilir .
Birden çok hesaba gönder
E-posta hesabı sorunlarını ortadan kaldırmaya yardımcı olmak için, e-postanızı farklı e-posta sağlayıcılarındaki birden çok e-posta hesabına gönderin . E-postalarınız bir kullanıcının Gmail hesabına ulaşmıyorsa, aynı e-postaları bir Yahoo hesabına, bir Hotmail hesabına ve normal bir POP3 hesabına (İSS tarafından sağlanan e-posta hesabınız gibi) gönderin.
E-postalar diğer e-posta hesaplarının tümüne veya bazılarına ulaşırsa, kodunuzun e-posta gönderdiğini bilirsiniz, ancak e-posta hesabı sağlayıcısı bir nedenle onları engelliyor olabilir. E-posta herhangi bir e-posta hesabına ulaşmazsa, sorunun kodunuzla ilgili olma olasılığı daha yüksektir.
Kodun form yöntemiyle eşleştiğinden emin olun
Form yönteminizi olarak ayarladıysanız , form değerlerinizi aramak için POST
kullandığınızdan emin olun $_POST
. Ayarladıysanız GET
veya hiç ayarlamadıysanız $_GET
, form değerlerinizi aramak için kullandığınızdan emin olun .
Form action
değerinizin doğru konumu gösterdiğinden emin olun
Form action
özniteliğinizin PHP posta kodunuzu işaret eden bir değer içerdiğinden emin olun .
<form action="send_email.php" method="POST">
Web barındırıcısının e-posta göndermeyi desteklediğinden emin olun
Bazı Web barındırma sağlayıcıları, sunucuları aracılığıyla e-posta gönderilmesine izin vermez veya etkinleştirmez. Bunun nedenleri değişebilir, ancak posta göndermeyi devre dışı bıraktılarsa, bu e-postaları sizin için göndermek için üçüncü bir tarafın kullanıldığı alternatif bir yöntem kullanmanız gerekecektir.
Teknik desteğe gönderilecek bir e-posta (çevrimiçi destek veya SSS'ye gittikten sonra), sunucunuzda e-posta özelliklerinin mevcut olup olmadığını netleştirmelidir.
localhost
Posta sunucusunun yapılandırıldığından emin olun
Yerel iş istasyonunuzda WAMP, MAMP veya XAMPP kullanarak geliştirme yapıyorsanız, büyük olasılıkla iş istasyonunuza bir e-posta sunucusu kurulmamıştır. Bu olmadan, PHP varsayılan olarak posta gönderemez.
Temel bir posta sunucusu kurarak bunun üstesinden gelebilirsiniz. Windows için ücretsiz Mercury Mail'i kullanabilirsiniz .
E-postalarınızı göndermek için SMTP de kullanabilirsiniz. Bkz bu büyük cevabı dan Vikas dwivedi Bunun nasıl öğrenmek için.
PHP'nin özel özelliğini etkinleştirin mail.log
MTA'nızın ve PHP'nin günlük dosyasına ek olarak, özellikle işlev için günlük kaydınımail()
etkinleştirebilirsiniz . Tam SMTP etkileşimini değil, en azından işlev çağrısı parametrelerini ve çağrı komut dosyasını kaydetmez.
ini_set("mail.log", "/tmp/mail.log");
ini_set("mail.add_x_header", TRUE);
Ayrıntılar için http://php.net/manual/en/mail.configuration.php adresine bakın. (Bu bu seçenekleri etkinleştirmek için en iyisi php.ini
ya .user.ini
ya .htaccess
belki.)
Bir posta test servisine danışın
MTA / web sunucusu kurulumunuzu test etmek için kullanabileceğiniz çeşitli teslimat ve spamminess kontrol hizmetleri vardır. Genellikle bir posta araştırması gönderirsiniz: adresleri, ardından bir teslimat raporu ve daha sonra daha somut başarısızlıklar veya analizler alırsınız:
- mail-tester.com (ücretsiz / basit)
- glockapps.com (ücretsiz / $$$)
- senforensics.com (kayıt / $$$)
- mailtrap.io (pro / $$$)
- ultratools /… / emailTest (ücretsiz / yalnızca MX kontrolleri)
- Çeşitli: http://www.verticalresponse.com/blog/7-email-testing-delivery-tools/
Farklı bir posta gönderisi kullanın
PHP'nin yerleşik mail()
işlevi kullanışlıdır ve çoğu zaman işi yapar , ancak eksiklikleri vardır . Neyse ki, yukarıda özetlenen sorunların çoğunu ele alma dahil olmak üzere daha fazla güç ve esneklik sunan alternatifler var:
- En popüler varlık: PHPMailer
- Aynı şekilde özellikli: SwiftMailer
- Hatta eski PEAR :: Mail bile .
Bunların tümü profesyonel bir SMTP sunucusu / servis sağlayıcısı ile birleştirilebilir. (Çünkü e-posta kurulumu / yapılandırılabilirliği söz konusu olduğunda, tipik 08/15 paylaşılan web barındırma planları tutulur veya kaçırılır.)
Posta işlevine bir posta başlığı ekleyin:
$header = "From: [email protected]\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>';
}
- Posta işlevinde daima başlık göndermeyi deneyin.
- Localhost aracılığıyla posta gönderiyorsanız, posta göndermek için SMTP ayarlarını yapın.
- Bir sunucu üzerinden posta gönderiyorsanız, sunucunuzda e-posta gönderme özelliğinin etkin olup olmadığını kontrol edin.
E-postanızı göndermek için bir SMTP yapılandırması kullanıyorsanız, bunun yerine PHPMailer'ı kullanmayı deneyin . Kitaplığı https://github.com/PHPMailer/PHPMailer adresinden indirebilirsiniz .
E-postamı bu şekilde göndererek oluşturdum:
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 = "[email protected]";
$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";
}
Posta göndermeden önce birkaç başlık eklemeniz yeterlidir:
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$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: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
Ve bir şey daha. mail()
Fonksiyon localhost çalışmıyor. Kodunuzu bir sunucuya yükleyin ve deneyin.
Aşağıdakileri yaparak 000webhost'ta benim için çalıştı:
$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";
E-postayı gönderirken doğrudan e-posta adresini girin:
mail('[email protected]', $subject, $message, $headers)
Kullanın ''
ve kullanmayın ""
.
Bu kod çalışıyor, ancak e-posta yarım saat gecikmeli olarak alındı.
Çoğunlukla mail()
işlev, paylaşılan barındırmada devre dışı bırakılır. SMTP kullanmak daha iyi bir seçenektir. En iyi seçenek Gmail veya SendGrid olacaktır.
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();
}
?>
Yalnızca mail()
işlevi kullanıyorsanız , yapılandırma dosyasını tamamlamanız gerekir.
Posta genişletmeyi açmanız SMTP smtp_port
ve vb. Ayarlamanız ve en önemlisi kullanıcı adınız ve şifreniz gerekir. Bu olmadan posta gönderilemez. Ayrıca, PHPMail
göndermek için sınıfı kullanabilirsiniz .
Bu iki şeyi ayrı ayrı ve birlikte deneyin:
- kaldır
if($_POST['submit']){}
- kaldır
$from
(sadece bağırsaklarım)
Bence bu hile yapmalı. if(isset
PHP'yi HTML'den ayırmak için vücuttaki değişkenlere bir bitiştirme ekledim ve ekledim.
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$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>';
}
}
?>
Bunu ileride bulan biri için, kullanmanızı tavsiye etmem mail
. Buna değinen bazı cevaplar var, ama nedeni değil.
PHP'nin mail
işlevi yalnızca opak değildir , işi yapmak için kullandığınız MTA'ya (yani Sendmail ) tamamen güvenir . mail
olacak sadece MTA bunu kabul etmemesi halinde size (göndermeye çalıştığınız zaman yani Sendmail aşağı idi). Postanın teslim edildiği için başarılı olup olmadığını size söyleyemez. Bu nedenle ( John Conde'nin cevap ayrıntıları gibi), şimdi MTA'nın günlükleriyle oynamaya başlayacak ve düzeltilemeyen başarısızlığı size yeterince anlatacağını umacaksınız. Paylaşılan bir ana bilgisayardaysanız veya MTA günlüklerine erişiminiz yoksa, şansınız kalmaz. Ne yazık ki, Linux için çoğu vanilya kurulumunun varsayılanı bunu bu şekilde halleder.
Bir posta kitaplığı ( PHPMailer , Zend Framework 2+, vb.) mail
,. Doğrudan alıcı posta sunucusuna bir soket açar ve ardından SMTP posta komutlarını doğrudan bu soket üzerinden gönderir. Başka bir deyişle, sınıf kendi MTA'sı gibi davranır (kütüphanelere mail
postayı en sonunda göndermek için kullanmalarını söyleyebileceğinizi unutmayın , ancak bunu kesinlikle yapmamanızı tavsiye ederim).
Bu, daha sonra alıcı sunucudan gelen yanıtları doğrudan görebileceğiniz anlamına gelir (örneğin, PHPMailer'da, hata ayıklama çıktısını açabilirsiniz ). Artık bir postanın gönderilemediğini veya nedenini tahmin etmenize gerek yok.
SMTP kullanıyorsanız (yani
isSMTP()
, arıyorsanız),SMTPDebug
özelliği kullanarak SMTP görüşmesinin ayrıntılı bir dökümünü alabilirsiniz .Komut dosyanıza buna benzer bir satır ekleyerek bu seçeneği ayarlayın:
$mail->SMTPDebug = 2;
Ayrıca daha iyi bir arayüzün avantajını da elde edersiniz. İle mail
bir kütüphanede vb ile tüm başlıklarını, ekleri kurmak zorunda, bunu yapmak için özel bir işlevi vardır. Ayrıca, işlevin tüm zor kısımları (başlıklar gibi) yaptığı anlamına gelir.
$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>";
}
CodeIgniter ile yapılandırma e-postasını kullanabilirsiniz . Örneğin, SMTP kullanma (basit yol):
$config = Array(
'protocol' => 'smtp',
'smtp_host' => 'mail.domain.com', // Your SMTP host
'smtp_port' => 26, // Default port for SMTP
'smtp_user' => '[email protected]',
'smtp_pass' => 'password',
'mailtype' => 'html',
'charset' => 'iso-8859-1',
'wordwrap' => TRUE
);
$message = 'Your msg';
$this->load->library('email', $config);
$this->email->from('[email protected]', 'Title');
$this->email->to('[email protected]');
$this->email->subject('Header');
$this->email->message($message);
if($this->email->send())
{
// Conditional true
}
Benim için çalışıyor!
Bunu dene
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>
';
}
}
Belki sorun posta sunucusunun yapılandırmasıdır. Bu tür sorunları önlemek veya posta sunucusu sorunu hakkında endişelenmenize gerek kalmaması için PHPMailer'ı kullanmanızı tavsiye ederim .
Posta göndermek için gereken her şeye sahip bir eklentidir ve hesaba katmanız gereken tek şey SMTP bağlantı noktasının (Bağlantı Noktası: 25 ve 465) etkinleştirilmesidir.
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 = '[email protected]';
$mail->Password = 'contrasenia';
$mail->SMTPSecure = 'ssl';
$mail->Port = 465;
// Recipients
$mail->setFrom('[email protected]', 'my name');
$mail->addAddress('[email protected]');
// 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;
}
Sunucunuzda Sendmail'in kurulu olduğundan emin olun.
Kodunuzu kontrol ettiyseniz ve orada bir sorun olmadığını doğruladıysanız, / var / mail adresine gidin ve bu klasörün boş olup olmadığını kontrol edin.
Boşsa, yapmanız gerekenler:
sudo apt-get install sendmail
bir Ubuntu sunucusundaysanız.
Öncelikle mail () işlevi için çok fazla parametreniz olabilir ... En fazla beşe sahip olabilirsiniz, mail(to, subject, message, headers, parameters);
$from
Değişken gittiği sürece , eğer Linux cPanel kullanıyorsanız, bu otomatik olarak web barındırıcınızdan gelmelidir . Otomatik olarak cPanel kullanıcı adınızdan ve IP adresinizden gelir.
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: yoursite.com';
$to = '[email protected]';
$subject = 'Customer Inquiry';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
Ayrıca mail () fonksiyonunuzda doğru değişken sırasına sahip olduğunuzdan emin olun.
Bu sırayla, yoksa işe yaramama şansı var.mail($to, $subject, $message, etc.)
PHP ile posta göndermede sorun yaşıyorsanız, PHPMailer veya SwiftMailer gibi bir alternatif düşünün .
PHP ile posta göndermem gerektiğinde genellikle SwiftMailer'ı kullanırım.
Temel kullanım:
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('[email protected]' => 'Jane Doe'))
// The to address(es)
->setTo(array('[email protected]' => '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);
}
SwiftMailer'ın nasıl kullanılacağı hakkında daha fazla bilgi için resmi belgelere bakın .
Harici posta kullanmak istemeyen ve özel bir Linux sunucusunda posta () göndermek isteyenler için.
PHP'nin postalanma şekli php.ini
bölümünde açıklanmıştır [mail function]
.
Parametre sendmail-path
sendmail'in nasıl çağrıldığını açıklar. Varsayılan değer sendmail -t -i
, bu nedenle sendmail -t -i < message.txt
Linux konsolunda bir çalışma gerçekleştirirseniz - işiniz bitmiş olacak. Ayrıca mail.log
hata ayıklamaya ekleyebilir ve mail () 'nin gerçekten çağrıldığından emin olabilirsiniz.
Farklı MTA'lar uygulayabilir sendmail
. Sadece bu isimdeki ikili dosyalarına sembolik bir bağlantı kurarlar. Örneğin, Debian'da varsayılan Postfix'tir . MTA'nızı posta göndermek için yapılandırın ve konsoldan ile test edin sendmail -v -t -i < message.txt
. Dosya message.txt
, bir iletinin tüm başlıklarını içermelidir ve bir gövde, zarf için hedef adresi To:
başlıktan alınacaktır . Misal:
From: [email protected]
To: [email protected]
Subject: Test mail via sendmail.
Text body.
Ben ssmtp'yi MTA olarak kullanmayı tercih ediyorum çünkü basit ve açık portlara sahip bir arka plan programı çalıştırmayı gerektirmiyor. ssmtp yalnızca localhost'tan posta göndermek için uygundur . Ayrıca hesabınız üzerinden genel posta hizmetinde kimliği doğrulanmış e-posta gönderebilir. Ssmtp'yi kurun ve yapılandırma dosyasını düzenleyin /etc/ssmtp/ssmtp.conf
. Ayrıca Unix hesaplarına yerel sistem postası alabilmek için (örneğin cron işlerinden root'a uyarılar) /etc/ssmtp/revaliases
dosyayı yapılandırın .
Yandex postasındaki hesabım için yapılandırmam:
[email protected]
mailhub=smtp.yandex.ru:465
FromLineOverride=YES
UseTLS=YES
[email protected]
AuthPass=password
Bu yalnızca küçük bir avuç kullanıcıyı etkileyecek, ancak bu küçük bir avuç için belgelenmesini istiyorum. Bu küçük bir avuç dolusu üye, bu sorun nedeniyle 6 saat boyunca çalışan bir PHP posta betiğini giderdi.
Www.AceITLab.com adresinden XAMPP çalıştıran bir üniversiteye gidiyorsanız, profesörümüzün bize söylemediğini bilmelisiniz: AceITLab güvenlik duvarı (Windows güvenlik duvarı değil), XAMPP'de MercuryMail'i engeller. Alternatif bir posta istemcisi kullanmanız gerekecek, pear bizim için çalışıyor. Düşük güvenlik ayarlarına sahip bir Gmail hesabına göndermeniz gerekecek.
Evet, biliyorum, bu gerçek dünya e-postası için tamamen işe yaramaz. Ancak, gördüğüm kadarıyla, akademik ortamlar ve gerçek dünyanın çoğu zaman çok az ortak noktası vardır.
Bu kodu yerel bir sunucuda çalıştırıyorsanız (yani geliştirme amacıyla bilgisayarınız), e-postayı alıcıya göndermez. .txt
Adlı bir klasörde bir dosya oluşturacaktır mailoutput
.
Gibi durumda, ücretsiz bir hortumla sulama hizmeti kullanıyorsanız 000webhost
veya hostinger
bu servis sağlayıcılar devre dışı mail()
Sana bu özelliği destekleyen olup olmadığını görmek için onlarla temas tercih vb e-posta sahteciliği spam, istenmeyen kullanımları önlemek için işlevi.
Servis sağlayıcının mail () işlevini desteklediğinden eminseniz, daha fazla referans için bu PHP kılavuzuna bakabilirsiniz,
Barındırma hizmetinizin mail () işlevini desteklediği hava durumunu kontrol etmek için, bu kodu çalıştırmayı deneyin (alıcı e-posta adresini değiştirmeyi unutmayın) :
<?php
$to = '[email protected]';
$subject = 'the subject';
$message = 'hello';
$headers = 'From: [email protected]' . "\r\n" .
'Reply-To: [email protected]' . "\r\n" .
'X-Mailer: PHP/' . phpversion();
mail($to, $subject, $message, $headers);
?>
Debian 10.0.0 ('Buster') için Sendmail kurulumu aslında önemsizdi!
php.ini
[mail function]
sendmail_path=/usr/sbin/sendmail -t -i
; (Other directives are mostly windows)
Standart sendmail paketi kurulumu (' gönder'e izin verilir):
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
Çeşitli yararlı komutlar:
which sendmail # /usr/sbin/sendmail
which sendmailconfig # /usr/sbin/sendmailconfig
man sendmail # Documentation
systemctl restart sendmail # As and when required
Doğrulama (gönderme yeteneği)
echo "Subject: sendmail test" | sendmail -v <yourEmail>@gmail.com
Yukarıdakiler yaklaşık 5 dakika sürdü. Sonra 5 saatimi boşa harcadım ... Spam klasörünüzü kontrol etmeyi unutmayın !
Birkaç olasılık var:
Bir sunucu sorunuyla karşı karşıyasınız. Sunucunun herhangi bir posta sunucusu yok. Yani postanız çalışmıyor, çünkü kodunuz iyi ve posta türle çalışıyor.
Kaydedilen değeri almıyorsunuz. Kodunuzu statik bir değerle deneyin.
Posta göndermek için SMTP postalarını kullanın ...
Hatalarınızı şu şekilde görebilirsiniz:
error_reporting(E_ALL);
Ve örnek kodum:
<?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 = '[email protected]'; // SMTP username
$mail->Password = 'password'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, 'ssl' also accepted
$mail->From = '[email protected]';
$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';
?>
Hostgator'da barındırılan bir uygulamada takıldıysanız, sorunumu bu çözdü. Ayrıntılı çözümü yayınlayan adama çok teşekkürler. Bağlantının bir gün çevrimdışı olması durumunda, işte bir özet var:
- Sunucunuzda sendmail yolunu bulun. Bunu kontrol etmenin basit bir yolu, geçici olarak oluşturulan bilgi okumak için, sadece erişecek bir sayfa aşağıdaki kodu yazmaktır:
<?php phpinfo(); ?>
. Bu sayfayı açın ve arayınsendmail path
. (O zaman bu kodu kaldırmayı unutmayın!) - Sorun ve düzeltme: Sendmail yolunuz yalnızca diyorsa
-t -i
, sunucunuzu düzenleyinphp.ini
ve aşağıdaki satırı ekleyin:sendmail_path = /usr/sbin/sendmail -t -i;
Ancak PHP mail()
işlevi ile posta gönderebildikten sonra , kimliği doğrulanmamış e-posta göndermediğini öğrendim, bu da başka bir soruna neden oldu. E-postaların tümü Hotmail'imin önemsiz posta kutusuna düşüyordu ve bazı e-postalar asla teslim edilmedi, sanırım bu da kimlik doğrulamalarının yapılmamasıyla ilgili. Ben geçmek için karar verdik mail()
için PHPMailer
sonuçta SMTP ile.