简体   繁体   English

使用准备好的语句的PHP更新查询不起作用

[英]php update query using prepared statement not working

I am doing updation of table using following prepared statements as follows: 我正在使用以下准备的语句来更新表:

 $query = " UPDATE signup SET name=?,password=?,verify_key=? WHERE email=? ";
 $stmt=$conn->prepare($query);
 $stmt->bind_param("ssss",$dname,$password,$verify_key,$email);
 $stmt->execute();
 $stmt->close();

But it is giving error on which I am stuck for long time: 但这给了我长期困扰的错误:

Fatal error: Call to a member function bind_param() on boolean in somefile.php on line 75 致命错误:在第75行,在somefile.php中的布尔值上调用成员函数bind_param()

Structure of table in database is as follow: 数据库中表的结构如下:

mysql> desc signup;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| sid        | int(11)      | NO   | PRI | NULL    | auto_increment |
| name       | varchar(100) | NO   |     | NULL    |                |
| email      | varchar(100) | NO   | UNI | NULL    |                |
| password   | varchar(255) | NO   |     | NULL    |                |
| verify_key | varchar(255) | NO   |     | NULL    |                |
| active     | bit(1)       | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)

Note : I printed $dname,$password,$verify_key,$email. 注意:我打印了$ dname,$ password,$ verify_key,$ email。 All printed correct string values. 所有打印的正确字符串值。

Entire PHP code: 整个PHP代码:

<?php
session_start();
ob_start();
require_once("connection.php");

$dname=$_POST['dname'];
$email=$_POST['email'];
$password=$_POST['password'];

if(empty($dname) || empty($email) || empty($password))
  die("Enter correct details.");

$password = password_hash($password,PASSWORD_DEFAULT); // generate hash for password
$verify_key = password_hash(RandomString(),PASSWORD_DEFAULT); // generate hash for verification key

/* RandomString() generates random string */
function RandomString($length = 32) {
      $randstr;
      //our array add all letters and numbers if you wish
      $chars = array(
          'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'p',
          'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '1', '2', '3', '4', '5',
          '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
          'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z');
      for ($rand = 0; $rand <= $length; $rand++) {
          $random = rand(0, count($chars) - 1);
          $randstr .= $chars[$random];
      }
      return $randstr;
}  // function RandomString()  over

/*  Mail Sending Code */
function sendMail($email,$verify_key){
$to = $email;
$subject = 'Something';
$mail_link='https://127.0.0.1/rs/signupCheck.php?email='.$email.'&key='.$verify_key;
$message = "
<html>
<head>
  <title></title>
</head>
<body>
<p>
<a href='> Click this link to verify your account </a>
</p>
</body>
</html>
";

// To send HTML mail, the Content-type header must be set
$headers[] = 'MIME-Version: 1.0';
$headers[] = 'Content-type: text/html; charset=iso-8859-1';
$headers[] = 'From: Something <Something>';
$res = mail($to, $subject, $message, implode("\r\n", $headers));
return $res;  //check officially mail is sent or not
}  // function sendMain() ends


// check if email already exists in database
$query = " SELECT active FROM signup WHERE email=?";
$stmt = $conn->prepare($query);
$stmt->bind_param("s",$email);
$stmt->execute();
$stmt->bind_result($dbactive);
if($stmt->fetch()){     // email is present in DB
if($dbactive==1){        // status=1
  $stmt->close();
  die("Account already created. Try forget passwod if you can't access it.");
}
else{
  /* Record is already present with status=0 , override all the details */
  if(sendMail($email,$verify_key)) {  // send mail first then update DB
     $query = " UPDATE `signup` SET `name`=?,`password`=?,`verify_key`=? WHERE `email`=? ";
     $stmt=$conn->prepare($query);
     $stmt->bind_param("ssss",$dname,$password,$verify_key,$email);
     $stmt->execute();
     $stmt->close();
     die("We sent you verification link on mail. Click it to verify !!!");
  }
  else {
    die("Mail sending failed. Try again !!!");
  }
}
}      // email already present with either status=1 or status=0
else { // Insert account details in DB , nothing is present in DB for user
     if(sendMail($email,$verify_key)) {  // send mail first then update DB
       $query = "INSERT INTO signup (sid,name,email,password,verify_key,active)VALUES(?,?,?,?,?,?)";
       $stmt = $conn->prepare($query);
       $stmt->bind_param("issssi",$fixed_sid='',$dname,$email,$password,$verify_key,$fixed_active=0);
        /* Notice $fixed_sid and $fixed_active , it is needed
           you can't have fixed values in bind_param
        */
       $stmt->execute();
       $stmt->close();
       die("We sent you verification link on mail. Click it to verify !!!");
     }
     else {
       die("Mail sending failed. Try again !!!");
     }
}    // first time data entry in DB
?>

Add $stmt->close(); 添加$stmt->close(); before your next mysqli interaction. 在您下一次mysqli交互之前。

if(sendMail($email,$verify_key)) {  // send mail first then update DB
    $stmt->close();
    $query = " UPDATE `signup` SET `name`=?,`password`=?,`verify_key`=? WHERE `email`=? ";

or you might just always want to execute the close after you're finished with your previous mysql interaction. 或者您可能总是希望在完成之前的mysql交互后执行close

eg: 例如:

$query = " SELECT active FROM signup WHERE email=?";
$stmt = $conn->prepare($query);
$stmt->bind_param("s",$email);
$stmt->execute();
$stmt->bind_result($dbactive);
$stmt->close();

and remove the $stmt->close(); 并删除$stmt->close(); from the if . if I've never seen official documentation on this but I've seen other threads were this was an underlying issue. 我从没看过官方文档,但是我看过其他线程,这是一个潜在的问题。 The manual page itself actual almost states the opposite: 手册页实际上几乎是相反的:

So, while explicitly closing open connections and freeing result sets is optional , doing so is recommended. 因此,尽管显式关闭打开的连接和释放结果集是可选的 ,但建议这样做。

that is optional is false (... in my experience, I also primarily use PDO). is optional是错误的(...根据我的经验,我也主要使用PDO)。

I had an issue in my query and this line of code help me to diagnose my error 我的查询出现问题,这行代码可帮助我诊断错误

mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

here is reference may be it help you 这是参考可能对您有帮助
https://websitebeaver.com/prepared-statements-in-php-mysqli-to-prevent-sql-injection https://websitebeaver.com/prepared-statements-in-php-mysqli-to-prevent-sql-injection

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM