0

我正在拼凑 PHP 脚本来学习如何构建注册表单。该表单应该获取信息,检查空字段,然后插入数据库,如果成功则发送一封电子邮件,然后重定向到成功页面。

使用下面的代码,似乎在页面加载时认为某些内容已输入到数据库中,然后在页面加载时立即重定向到成功页面。我哪里错了?

<?php
session_start();
$_SESSION['user'] = $user;

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

 if(empty($_POST["first_name"]))
 {
   $first_name_err = "<p>What is your first name?</p>";
 }
 if(empty($_POST["last_name"]))
 {
   $last_name_err = "<p>What is your last name?</p>";
 }
 //checks email
 if(empty($_POST["email"]))
 {
   $email_err = "<p>What is your email address?</p>";
 }
 if(empty($_POST["phone"]))
 {
   $phone_err = "<p>What is your phone number?</p>";
 }
  if(empty($_POST["password"]))
 {
   $pass_err = "<p>Please enter your password</p>";
 }

}

require_once('includes/db_connect.php');

// Get values from form
$first_name = mysql_real_escape_string($_POST['first_name']);
$last_name = mysql_real_escape_string($_POST['last_name']);    
$email = mysql_real_escape_string($_POST['email']);
$phone = mysql_real_escape_string($_POST['phone']);
$password = mysql_real_escape_string($_POST['password']);


// Insert data into mysql
$sql="INSERT INTO dontblame (first_name, last_name, email, phone, password, reg_date)
VALUES ('$first_name', '$last_name', '$email', '$phone', SHA1('$password'), NOW())";
$result = mysql_query($sql);

// if successfully insert data into database, displays message "Successful".
if($result){
 //Send to Success Page
header('Location: ../thankyou.php?first_name=' . htmlentities($first_name));
    }
 else {
  echo "ERROR there was a problem with the registration form. Please try again.";
    } 
    // close mysql
    mysql_close();

if(IsInjected($email))
{
    echo "Please don't SPAM.";
    exit;
}

$email_from = 'hello@dontblame.co';//<== update the email address
$email_subject = "Welcome to Jon's First Registration Form";
$email_body = "Hi, $first_name,\n".
    "\n Welcome to Jon's First Registration Form! Below is your login information: \n\n Username: $email \n Password: $password \r\n".

$to = "$email";//<== update the email address
$headers = "From: $email_from \r\n";
$headers .= "Reply-To: $email_from \r\n";
//Send the email!
mail($to,$email_subject,$email_body,$headers);
//done. redirect to thank-you page.

// Function to validate against any email injection attempts
function IsInjected($str){
  $injections = array('(\n+)',
              '(\r+)',
              '(\t+)',
              '(%0A+)',
              '(%0D+)',
              '(%08+)',
              '(%09+)'
              );
  $inject = join('|', $injections);
  $inject = "/$inject/i";
  if(preg_match($inject,$str))
    {
    return true;
  }
  else
    {
    return false;
  }
}

?>
4

3 回答 3

1

几个错误:

1)第一个if ($_SERVER['REQUEST_METHOD'] == 'POST') {应该跨越一切,或者更好,

if ($_SERVER['REQUEST_METHOD'] != 'POST') { ...redirect somewhere...}

编辑:不同之处在于您的版本要求您“一直记住”上述条件。如果您遵循“提前退出”的想法,那么您阅读的代码将在您到达那里时被执行。这使得它更易于阅读和维护。(还有其他因素,例如降低圈复杂度,但暂时忽略它。)

2) sql 查询将始终有效并返回结果,因此无法控制是否输入了所有内容。原因是如果没有给出 $_POST['email'],$email 可以为空

$email = mysql_real_escape_string($_POST['email']);

所以查询将简单地插入一个空的电子邮件地址而不会出错。(除非您将该字段设置为唯一,但这是另一回事。)

编辑:如果您使用 PhpMyAdmin(除非您知道 MySQL 的进出,否则您肯定应该使用),转到表的结构,并添加唯一类型的索引(由字母 u 表示)。或者,您可以向下滚动到“indeces”,然后单击添加索引。(语法基本上是一个 ALTER TABLE,但现在适用于图形界面)。

3)如果 isInjected() 函数返回 true,您的脚本将退出并显示“请勿发送垃圾邮件”消息。但是,您已经设置了 Location-header,这样就永远不会看到不要垃圾邮件。

于 2013-06-04T17:23:55.320 回答
0

整个事情需要包装在后期检查中:

if ($_SERVER['REQUEST_METHOD'] == 'POST') {

您只有包含在其中的验证代码。在你这样做之前,它总是会在加载时插入一个空白行,因为没有条件。

此外,您的验证码似乎不完整。$pass_err它会创建一个带有错误消息的变量,但你永远不会对它做任何事情。

您需要移动您的电子邮件发送代码,以便它在重定向之前执行。目前它在重定向之后执行,这是一个问题,因为执行可能并不总是到达那个点(一旦浏览器收到重定向标头,它将与服务器断开连接,进而停止 PHP 执行)。

于 2013-06-04T16:58:49.883 回答
0

一旦你header() 在代码中找到你的函数,你就会自动进入你的成功页面。

header('Location: ../thankyou.php?first_name=' . htmlentities($first_name));

该代码告诉 php 直接进入您的thankyou.php 页面并退出其余代码。一个简单的解决方案是在重定向之前检查您是否已提交表单。

祝你好运

编辑:

如果您的问题是未发送电子邮件,则需要将电子邮件发送放在标题之前。假设标头尚未发送,标头在到达该行时立即退出代码。有关此处标头函数的更多信息,请参见phps header()

于 2013-06-04T16:59:47.110 回答