PHP 联系表最佳实践:输入验证无效
PHP Contact Form Best Practice: Input Validation not working
我的表单输入验证没有像我预期的那样工作。
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: Kontaktformular';
$to = 'meine@mail.de';
$subject = 'Kontaktformular';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
在这部分我尝试验证输入:
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if ($email === FALSE) {
echo 'Invalid email';
exit(1);
}
$body = str_replace("\n.", "\n..", $body);
如果输入不为 NULL,我现在尝试发送邮件:
if(isset($_POST['Submit'])) {
if (mail ($to, $subject, $body, $from)) {
echo '<p>Message was sent!</p>';
} else {
echo '<p>Something went wrong :( Please try again</p>';
}
} else {
die ("Direct access not allowed!");
}
?>
我的问题是,我的代码 returns 要么是 "Invalid email" 要么是 "Direct access not allowed!",但我不确定我做错了什么。
我的HTML表格:
<form method="post" action="php-contact.php" class="animated fadeIn">
<label>Name</label>
<input name="name" placeholder="Name">
<label>E-Mail</label>
<input name="email" type="email" placeholder="E-Mail, zum antworten…">
<label>Nachricht</label>
<textarea name="message" placeholder="Nachricht…"></textarea>
<input id="submit" name="submit" type="submit" value="Absenden">
</form>
我尝试使用这些代码示例:
Proper prevention of mail injection in PHP
除了您遇到的误导性错误消息外,这是您的问题:
isset($_POST['Submit'])
因为表单输入是:
<input name="submit">
这些东西区分大小写。
如何调试它?
- 首先,
print_r($_POST);
看看你到底得到了什么。
- 其次,避免
isset()
,直到您确保一切正常。抑制有用的 通知从来都不是一个好的策略。
您处理的顺序有误。在尝试分配给用于构建消息的变量之前,您首先需要检查 POSTed 数据中是否存在各种表单字段。
<?php
/* test METHOD and if fields are present in POST array */
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['submit'], $_POST['name'], $_POST['email'], $_POST['message'] ) ){
/* do some sanitation and validation on user input */
$name=filter_input( INPUT_POST, 'name', FILTER_SANITIZE_STRING );
$email=filter_var( filter_input( INPUT_POST, 'email', FILTER_SANITIZE_EMAIL ), FILTER_VALIDATE_EMAIL );
$message=filter_input( INPUT_POST, 'name', FILTER_SANITIZE_STRING );
/* if the sanitation and validation succeeds, continue processing */
if( $name && $email && $message ){
$from = 'From: Kontaktformular';
$to = 'meine@mail.de';
$subject = 'Kontaktformular';
$body = "From: $name\nE-Mail: $email\nMessage:\n $message";
$status=mail( $to, $subject, $body, $from );
echo $status ? '<p>Message was sent!</p>' : '<p>Something went wrong :( Please try again</p>';
} else {
echo "bogus!"
}
} else {
die("Direct access not allowed!");
}
?>
这是另一个如何构建此验证脚本的示例。请注意,我建议将邮件正文发送为 text/plain,这样您的电子邮件客户端就不会解释任何虚假的 html。此外,我还添加了一些最大长度检查,以便用户无法提交任意长度的数据。
<?php
// check request method
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
throw new \RuntimeException('Invalid request method');
}
// get all input vars
$name = isset($_POST['name']) ? $_POST['name'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$message = isset($_POST['message']) ? $_POST['message'] : null;
// validate values
if (empty($name) || empty($email) || empty($message)) {
throw new \RuntimeException('Invalid values provided');
}
if (strlen($name) > 64) {
throw new \RuntimeException('Name can have max 64 chars');
}
if (strlen($email) > 32) {
throw new \RuntimeException('Email can have max 32 chars');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \RuntimeException('Invalid email format');
}
if (strlen($message) > 1023) {
throw new \RuntimeException('Message can have max 1023 chars');
}
// send mail
$headers = "From: your@email.com" . "\r\n";
$headers.= "Content-Type: text/plain";
$to = "meine@mail.de";
$subject = "Kontaktformular";
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
if (mail($to, $subject, $body, $headers)) {
echo '<p>Message was sent!</p>';
} else {
echo '<p>Something went wrong :( Please try again</p>';
}
我的表单输入验证没有像我预期的那样工作。
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
$from = 'From: Kontaktformular';
$to = 'meine@mail.de';
$subject = 'Kontaktformular';
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
在这部分我尝试验证输入:
$email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
if ($email === FALSE) {
echo 'Invalid email';
exit(1);
}
$body = str_replace("\n.", "\n..", $body);
如果输入不为 NULL,我现在尝试发送邮件:
if(isset($_POST['Submit'])) {
if (mail ($to, $subject, $body, $from)) {
echo '<p>Message was sent!</p>';
} else {
echo '<p>Something went wrong :( Please try again</p>';
}
} else {
die ("Direct access not allowed!");
}
?>
我的问题是,我的代码 returns 要么是 "Invalid email" 要么是 "Direct access not allowed!",但我不确定我做错了什么。
我的HTML表格:
<form method="post" action="php-contact.php" class="animated fadeIn">
<label>Name</label>
<input name="name" placeholder="Name">
<label>E-Mail</label>
<input name="email" type="email" placeholder="E-Mail, zum antworten…">
<label>Nachricht</label>
<textarea name="message" placeholder="Nachricht…"></textarea>
<input id="submit" name="submit" type="submit" value="Absenden">
</form>
我尝试使用这些代码示例: Proper prevention of mail injection in PHP
除了您遇到的误导性错误消息外,这是您的问题:
isset($_POST['Submit'])
因为表单输入是:
<input name="submit">
这些东西区分大小写。
如何调试它?
- 首先,
print_r($_POST);
看看你到底得到了什么。 - 其次,避免
isset()
,直到您确保一切正常。抑制有用的 通知从来都不是一个好的策略。
您处理的顺序有误。在尝试分配给用于构建消息的变量之前,您首先需要检查 POSTed 数据中是否存在各种表单字段。
<?php
/* test METHOD and if fields are present in POST array */
if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['submit'], $_POST['name'], $_POST['email'], $_POST['message'] ) ){
/* do some sanitation and validation on user input */
$name=filter_input( INPUT_POST, 'name', FILTER_SANITIZE_STRING );
$email=filter_var( filter_input( INPUT_POST, 'email', FILTER_SANITIZE_EMAIL ), FILTER_VALIDATE_EMAIL );
$message=filter_input( INPUT_POST, 'name', FILTER_SANITIZE_STRING );
/* if the sanitation and validation succeeds, continue processing */
if( $name && $email && $message ){
$from = 'From: Kontaktformular';
$to = 'meine@mail.de';
$subject = 'Kontaktformular';
$body = "From: $name\nE-Mail: $email\nMessage:\n $message";
$status=mail( $to, $subject, $body, $from );
echo $status ? '<p>Message was sent!</p>' : '<p>Something went wrong :( Please try again</p>';
} else {
echo "bogus!"
}
} else {
die("Direct access not allowed!");
}
?>
这是另一个如何构建此验证脚本的示例。请注意,我建议将邮件正文发送为 text/plain,这样您的电子邮件客户端就不会解释任何虚假的 html。此外,我还添加了一些最大长度检查,以便用户无法提交任意长度的数据。
<?php
// check request method
if ($_SERVER['REQUEST_METHOD'] != 'POST') {
throw new \RuntimeException('Invalid request method');
}
// get all input vars
$name = isset($_POST['name']) ? $_POST['name'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$message = isset($_POST['message']) ? $_POST['message'] : null;
// validate values
if (empty($name) || empty($email) || empty($message)) {
throw new \RuntimeException('Invalid values provided');
}
if (strlen($name) > 64) {
throw new \RuntimeException('Name can have max 64 chars');
}
if (strlen($email) > 32) {
throw new \RuntimeException('Email can have max 32 chars');
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \RuntimeException('Invalid email format');
}
if (strlen($message) > 1023) {
throw new \RuntimeException('Message can have max 1023 chars');
}
// send mail
$headers = "From: your@email.com" . "\r\n";
$headers.= "Content-Type: text/plain";
$to = "meine@mail.de";
$subject = "Kontaktformular";
$body = "From: $name\n E-Mail: $email\n Message:\n $message";
if (mail($to, $subject, $body, $headers)) {
echo '<p>Message was sent!</p>';
} else {
echo '<p>Something went wrong :( Please try again</p>';
}