【问题标题】:Why I get html code when I send email in php?为什么我在 php 中发送电子邮件时得到 html 代码?
【发布时间】:2021-03-01 08:16:59
【问题描述】:

您好,我正在为我的项目开发一个忘记密码的 php 系统。 我想向我的用户发送一封电子邮件,以便他们可以单击链接重置密码。 但是当我打开收件箱时,我得到的是 html 文本而不是链接。 我尝试了其他方法,例如在消息中添加标头,但它仍然是 html 代码。 这是我的代码:

<?php 

$errors = [];
$user_id = "";
$db = mysqli_connect('localhost', 'root', 'mySQLpassword',      'registration');

if (isset($_POST['login_user'])) {
  $user_id = mysqli_real_escape_string($db, $_POST['user_id']);
  $password = mysqli_real_escape_string($db, $_POST['password']);
  if (empty($user_id)) array_push($errors, "Username or Email is required");
  if (empty($password)) array_push($errors, "Password is required");

  if (count($errors) == 0) {
    $password = md5($password);
    $sql = "SELECT * FROM users WHERE username='$user_id' OR email='$user_id' AND password='$password'";
    $results = mysqli_query($db, $sql);

    if (mysqli_num_rows($results) == 1) {
      $_SESSION['username'] = $user_id;
      $_SESSION['success'] = "You are now logged in";
      header('location: index.php');
    }else {
      array_push($errors, "Wrong credentials");
    }
  }
}

if (isset($_POST['reset-password'])) {
  $email = mysqli_real_escape_string($db, $_POST['email']);
  
query = "SELECT email FROM users WHERE email='$email'";
  $results = mysqli_query($db, $query);

  if (empty($email)) {
    array_push($errors, "Your email is required");
  }else if(mysqli_num_rows($results) <= 0) {
    array_push($errors, "Sorry, no user exists on our system with that email");
  }
  $token = bin2hex(random_bytes(50));

  if (count($errors) == 0) {
    $sql = "INSERT INTO password_reset(email, token) VALUES ('$email', '$token')";
    $results = mysqli_query($db, $sql);

    $to = $email;
    $subject = "Reset your password";
    $msg = "Hi there, click on this <a href=\"new_password.php?token=" . $token . "\">link</a> to reset your password on our site";
    $msg = wordwrap($msg,70);
    $headers = "From: info@gmail.com";
    mail($to, $subject, $msg, $headers);
    header('location: pending.php?email=' . $email);
  }
}

if (isset($_POST['new_password'])) {
  $new_pass = mysqli_real_escape_string($db, $_POST['new_pass']);
  $new_pass_c = mysqli_real_escape_string($db, $_POST['new_pass_c']);

  $token = $_SESSION['token'];
  if (empty($new_pass) || empty($new_pass_c)) array_push($errors, "Password is required");
  if ($new_pass !== $new_pass_c) array_push($errors, "Password do not match");
  if (count($errors) == 0) {
    $sql = "SELECT email FROM password_reset WHERE token='$token' LIMIT 1";
    $results = mysqli_query($db, $sql);
    $email = mysqli_fetch_assoc($results)['email'];

    if ($email) {
      $new_pass = md5($new_pass);
      $sql = "UPDATE users SET password='$new_pass' WHERE email='$email'";
      $results = mysqli_query($db, $sql);
      header('location: index.php');
    }
  }
}
?>

任何帮助都将被排除在外!

【问题讨论】:

  • 这是学术代码还是用于生产网站?
  • 警告:当使用mysqli 时,您应该使用parameterized queriesbind_param 将用户数据添加到您的查询中。 请勿使用手动转义和字符串插值或连接来完成此操作,因为您总是会创建严重的SQL injection bugs。意外未转义的数据是一个严重的风险。使用绑定参数不那么冗长,并且更容易检查以检查您是否正确执行。
  • 注意:object-oriented interface to mysqli 明显不那么冗长,使代码更易于阅读和审核,并且不容易与过时的mysql_query 接口混淆,因为缺少单个i 会导致麻烦。示例:$db = new mysqli(…)$db-&gt;prepare("…") 过程接口是 PHP 4 时代的产物,不应在新代码中使用。此外,程序界面的错误检查和报告不那么严格,使调试工作受挫。
  • 托比,欢迎来到 StackOverflow。除了@tadman 关于查询的完全正确的 cmets 之外,您的代码还在您的密码上使用 md5 哈希(未加盐)。很长一段时间以来,md5 一直不被认为是安全的密码存储——而且可以说永远不应该如此。有许多更好且易于使用的替代品。请帮您的用户一个忙,在您解决数据库反馈并替换密码处理之前不要部署此代码。
  • 警告:编写访问控制层并不容易,而且有很多机会严重错误。任何现代的development framework,比如Laravel,都带有一个内置的authentication system,还有authentication libraries可以使用。至少遵循recommended security best practices 并且永远不要将密码存储为纯文本 或像 SHA1 或 MD5 这样的弱散列。

标签: php mysql email


【解决方案1】:

要发送 HTML 邮件,必须设置 Content-type 标头。

勾选mail documentation中的“Example #5 Sending HTML email”。

例子(这里$headers是一个数组):

$headers[] = 'Content-Type: text/html; charset=UTF-8';

【讨论】:

  • 当我添加你发布的代码时,它给了我这个错误:Fatal error: Uncaught Error: [] operator not supported for strings in C:\xampp\htdocs\app_logic.php:70 Stack trace: #0 C:\xampp\htdocs\enter_email.php(1): include() #1 {main} thrown in C:\xampp\htdocs\app_logic.php on line 70
  • 这是因为你的变量 $headers 是一个字符串。将其更改为数组。
  • 好吧,我的浏览器里还是一样的。它不发送 html 电子邮件。
  • 检查收到的电子邮件中的标题和内容(来源)。 Gmail,例如:support.google.com/mail/answer/29436
  • 你能解释一下怎么做吗?我很难按照您刚刚提供的链接中的说明进行操作。
猜你喜欢
  • 2012-05-10
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 2018-04-29
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多