PHP 5.x mail() 是否验证 "reply-to" 字段中域的有效性?
Does PHP 5.x mail() verify validity of domains in"reply-to" fields?
我最近 "prettifying" 尝试了一些经过验证的真正的电子邮件表单,使它们对移动设备更友好,并且认为我现在随机看到 PHP mail() 函数会发疯失败(并且 returning FALSE)。嗯,这不是随机的。在几乎拔掉我所有的头发之后,我终于意识到,每当我为成为我的 "reply-to" 地址的表单字段输入一个无效域时,mail() 就会失败,并且 return FALSE!请注意,这些不是 "malformed" 电子邮件地址(我已经检查过了),只是无效的地址(例如 "name@goooogle.com")。
如果您认为它很重要,我在下面包含了一个测试表单代码,但是您认为这是 PHP 的新 "feature",还是我的托管公司的服务器正在做的事情?如果它是 PHP,是否有一些新的 "testDomain()" 功能也可以添加到我的表单中?提醒犯了合法错误的用户会很好,但我可以肯定地告诉他们的是他们的邮件尝试失败了。毕竟,mail() 不会 return 一些友好的小错误代码来指示发生了什么,它只是 return 真或假。事实上,当它 return 为 false 时,它甚至不会在日志文件中报告错误。
说实话,这是我唯一一次让 mail() 在我的表单中失败。但我认为假设失败总是意味着域是坏的是不明智的。
<!DOCTYPE HTML>
<html>
<head> <title> Simple Test Email Form;</title> </head>
<!--
<?php
// define variables and set to empty values
$name = $email = $comments = ""; // $address = $citystate = $zip = $phone not used
$nameErr = $emailErr = $commentsErr = "";
$headers = $email_message = $sendersIP = "";
$email_to = "myaddress@mydomain.org"; // this is bogus!!!
$email_subject = "Private Mailform";
$status = "Form Not Yet Processed";
// some basic security functions
function clean_string($string) {
$bad = array("content-type","bcc:","to:","cc:","href");
return str_replace($bad,"",$string);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
// mail processing
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
if (empty($_POST["name"])) { $nameErr = " Name is required"; }
else { $name = test_input($_POST["name"]); }
if (empty($_POST["email"])) { $emailErr = "Email is required"; }
else { $email = test_input($_POST["email"]); }
// at least email should be validated
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) { $emailErr = "Invalid email format"; }
// keep senders IP, so we can watch for idiots.
$sendersIP = $_SERVER['REMOTE_ADDR'];
$comments = $_POST["comments"];
// So is all well?
if (empty($nameErr) && empty($emailErr) && empty($commentsErr) )
{
$email_message = $headers = "";
$email_message .= "Name: ".clean_string($name)."\n";
$email_message .= "Email: ".clean_string($email)."\n";
$email_message .= "IP: ".$sendersIP."\n";
$email_message .= "Comments: "."\n\n".clean_string($comments)."\n";
// create regular email headers
$headers .= 'From: '.$email."\r\n".
'Reply-To: '.$email."\r\n" .
'X-Mailer: PHP/' . phpversion();
$mail_sent = mail($email_to, $email_subject, $email_message, $headers);
// modify status string to show result
$status = ($mail_sent==TRUE) ? "mail() function returned TRUE" :" mail() function returned FALSE";
}
}
?>
-->
<body >
<table><tr><td style ="text-align:right;" width=100%>
<b><?php echo $status; ?></b><br>
<p><span >* = required fields.<br>Please double check your email address.</span></p>
<form name="contactform" method="post" enctype="multipart/form-data" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Name: <span class="error">*<?php echo $nameErr;?></span>
<input type="text" name="name" value="<?php echo $name;?>"><br>
Email: <span class="error">*<?php echo $emailErr;?></span>
<input type="text" name="email" value="<?php echo $email;?>"><br>
<br>
<div align="center"> ---- <span class="error">*</span> Message ---- <span class="error"><?php echo $commentsErr;?></span><br>
<textarea name="comments" wrap="physical" cols="40" rows="10" ><?php echo $comments;?></textarea>
<br><br>
</div>
<input name="submit" id="submit" type="submit" value="Submit" >
</form>
</td></tr></table>
</body>
</html>
没有。 mail()
不是为了那个。 可能您正在使用的 SMTP 会这样做,但这取决于所述服务器的设置。
PS:不要使用mail()
。这是非常原始的。使用phpmailer或其他工具让邮件发送更简单
mail
没有本地有效性检查。 Vanilla sendmail 也没有。因此,您的主机有可能让他们的 MTA 客户端执行此操作。您可以使用单独的邮件客户端对此进行测试。例如,ZF2、PHPMailer 和许多其他现代 PHP 邮件系统根本不使用 mail
功能。他们实际上打开一个套接字并直接发送邮件命令。这并不容易,但您可以修改它以向您发回实际命令和响应并查看 SMTP 事务失败的位置。
顺便说一句,您可以在它到达那一步之前添加您自己的验证。
// this will fail to send if the DNS for the domain has no MX records
if(!checkdnsrr($domain, 'MX')) {
// don't send
}
我最近 "prettifying" 尝试了一些经过验证的真正的电子邮件表单,使它们对移动设备更友好,并且认为我现在随机看到 PHP mail() 函数会发疯失败(并且 returning FALSE)。嗯,这不是随机的。在几乎拔掉我所有的头发之后,我终于意识到,每当我为成为我的 "reply-to" 地址的表单字段输入一个无效域时,mail() 就会失败,并且 return FALSE!请注意,这些不是 "malformed" 电子邮件地址(我已经检查过了),只是无效的地址(例如 "name@goooogle.com")。
如果您认为它很重要,我在下面包含了一个测试表单代码,但是您认为这是 PHP 的新 "feature",还是我的托管公司的服务器正在做的事情?如果它是 PHP,是否有一些新的 "testDomain()" 功能也可以添加到我的表单中?提醒犯了合法错误的用户会很好,但我可以肯定地告诉他们的是他们的邮件尝试失败了。毕竟,mail() 不会 return 一些友好的小错误代码来指示发生了什么,它只是 return 真或假。事实上,当它 return 为 false 时,它甚至不会在日志文件中报告错误。
说实话,这是我唯一一次让 mail() 在我的表单中失败。但我认为假设失败总是意味着域是坏的是不明智的。
<!DOCTYPE HTML>
<html>
<head> <title> Simple Test Email Form;</title> </head>
<!--
<?php
// define variables and set to empty values
$name = $email = $comments = ""; // $address = $citystate = $zip = $phone not used
$nameErr = $emailErr = $commentsErr = "";
$headers = $email_message = $sendersIP = "";
$email_to = "myaddress@mydomain.org"; // this is bogus!!!
$email_subject = "Private Mailform";
$status = "Form Not Yet Processed";
// some basic security functions
function clean_string($string) {
$bad = array("content-type","bcc:","to:","cc:","href");
return str_replace($bad,"",$string);
}
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
// mail processing
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
if (empty($_POST["name"])) { $nameErr = " Name is required"; }
else { $name = test_input($_POST["name"]); }
if (empty($_POST["email"])) { $emailErr = "Email is required"; }
else { $email = test_input($_POST["email"]); }
// at least email should be validated
if (!preg_match("/([\w\-]+\@[\w\-]+\.[\w\-]+)/",$email)) { $emailErr = "Invalid email format"; }
// keep senders IP, so we can watch for idiots.
$sendersIP = $_SERVER['REMOTE_ADDR'];
$comments = $_POST["comments"];
// So is all well?
if (empty($nameErr) && empty($emailErr) && empty($commentsErr) )
{
$email_message = $headers = "";
$email_message .= "Name: ".clean_string($name)."\n";
$email_message .= "Email: ".clean_string($email)."\n";
$email_message .= "IP: ".$sendersIP."\n";
$email_message .= "Comments: "."\n\n".clean_string($comments)."\n";
// create regular email headers
$headers .= 'From: '.$email."\r\n".
'Reply-To: '.$email."\r\n" .
'X-Mailer: PHP/' . phpversion();
$mail_sent = mail($email_to, $email_subject, $email_message, $headers);
// modify status string to show result
$status = ($mail_sent==TRUE) ? "mail() function returned TRUE" :" mail() function returned FALSE";
}
}
?>
-->
<body >
<table><tr><td style ="text-align:right;" width=100%>
<b><?php echo $status; ?></b><br>
<p><span >* = required fields.<br>Please double check your email address.</span></p>
<form name="contactform" method="post" enctype="multipart/form-data" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
Name: <span class="error">*<?php echo $nameErr;?></span>
<input type="text" name="name" value="<?php echo $name;?>"><br>
Email: <span class="error">*<?php echo $emailErr;?></span>
<input type="text" name="email" value="<?php echo $email;?>"><br>
<br>
<div align="center"> ---- <span class="error">*</span> Message ---- <span class="error"><?php echo $commentsErr;?></span><br>
<textarea name="comments" wrap="physical" cols="40" rows="10" ><?php echo $comments;?></textarea>
<br><br>
</div>
<input name="submit" id="submit" type="submit" value="Submit" >
</form>
</td></tr></table>
</body>
</html>
没有。 mail()
不是为了那个。 可能您正在使用的 SMTP 会这样做,但这取决于所述服务器的设置。
PS:不要使用mail()
。这是非常原始的。使用phpmailer或其他工具让邮件发送更简单
mail
没有本地有效性检查。 Vanilla sendmail 也没有。因此,您的主机有可能让他们的 MTA 客户端执行此操作。您可以使用单独的邮件客户端对此进行测试。例如,ZF2、PHPMailer 和许多其他现代 PHP 邮件系统根本不使用 mail
功能。他们实际上打开一个套接字并直接发送邮件命令。这并不容易,但您可以修改它以向您发回实际命令和响应并查看 SMTP 事务失败的位置。
顺便说一句,您可以在它到达那一步之前添加您自己的验证。
// this will fail to send if the DNS for the domain has no MX records
if(!checkdnsrr($domain, 'MX')) {
// don't send
}