Php Mysql绑定参数()错误

Php Mysql绑定参数()错误,php,mysqli,Php,Mysqli,如果我删除行unset($mysql);未结算(stmt)然后它会导致一个致命错误:绑定参数非对象错误。但是如果我取消设置,然后重新定义对象,那么效果很好。有人能解释为什么吗?警告:这是未经测试的。然而,我认为演示如何以更简洁的方式编写这篇文章很重要。特别是,将您的意图分解为特定的函数,每个函数做一件事并返回结果。这将有助于防止您的代码变得混乱,并使单独测试每个块变得更容易 <?php require_once'config.php'; if(isset($_POST['subscribe

如果我删除行
unset($mysql);未结算(stmt)然后它会导致一个致命错误:
绑定参数非对象错误
。但是如果我取消设置,然后重新定义对象,那么效果很好。有人能解释为什么吗?

警告:这是未经测试的。然而,我认为演示如何以更简洁的方式编写这篇文章很重要。特别是,将您的意图分解为特定的函数,每个函数做一件事并返回结果。这将有助于防止您的代码变得混乱,并使单独测试每个块变得更容易

<?php
require_once'config.php';
if(isset($_POST['subscribe'])){
  $email=$_POST['email'];

  //check the email if it is already subscribed or not
  if(strlen($email)>3){             
    $stmt=$mysql->prepare("SELECT * FROM subscribers WHERE email=?");
    $stmt->bind_param('s', $email);
    $stmt->execute();
    if($stmt->field_count > 0){ // if not then add
      unset($mysql); unset($stmt);
      $mysql=new mysqli(HOST,USER,PASS,DB);     
      $stmt=$mysql->prepare('INSERT INTO subscribers(email) VALUES (?)');
      $stmt->bind_param('s', $email);
      $stmt->execute();
      if($stmt->affected_rows>0){
        echo "subscribed";
      }
    } else { //else is there
      echo "Already there";
    }
  } else echo "empty string";
}
?>
查看更多信息

使用这种配置,您可以验证各个命令是否正常工作,而无需首先执行它们嵌套的结构。特别是,验证第二个sql查询非常重要:非绑定错误通常是因为找不到列或表。但是,也就是说,要意识到
prepare()
语句所做的是向服务器发送一个查询,以检查语法;该查询永远不会重新发送,而是一直“加载”在服务器中,直到您告诉它(使用另一条语句)将其删除。随后绑定参数时,该参数将发送到服务器并放入可用插槽(
)。由于此模型,您可以多次高效地执行此查询

请注意,如果服务器上的查询没有用于新参数的未绑定插槽,则绑定它的尝试将失败。如果服务器上的查询试图引用不可用的变量(如列名),则此步骤也将失败


从您提供的详细信息中不清楚确切的问题在哪里,但是如果您以更干净的方式编写代码,调试这些问题将变得更容易:是您的第二条sql语句不好吗?您是否没有从第一条语句中正确释放服务器资源

你为什么要重新连接?丢失未设置和重新定义。如果失败,var_将转储$mysql对象。哪一行抛出致命错误?您如何使用If($stmt->field_count>0),这意味着记录已经存在。如果($stmt->field_count==0),则应该正确。谢谢你。那是个错误。但是ans不是我需要知道的。$stmt->bind_param('s',$email);未设置后的行($mysql);未结算(stmt);正在抛出错误谢谢你的代码。但实际上,我想要一个概念性的描述,说明如果我不取消设置,为什么我的代码会发送错误。@Mohaiminusakib添加了更多详细信息,但您可能没有在这里提供足够的信息来解决您的问题。还请注意,您不需要取消设置;在这种情况下,这几乎肯定是矫枉过正。
require_once'config.php';

//It is always good to declare stuff like this in a central place
//That way they're easy to change, and you change it everywhere you have that express intent
$SQL_FIND_SUBSCRIPTION = "SELECT * FROM subscribers WHERE email=?";
$SQL_NEW_SUBSCRIPTION = "INSERT INTO subscribers(email) VALUES (?)";

//Functions make testing easy!
static function attemptSubscription($postValues, &$returnMsg) {
  if (   isset($postValues['subscribe']) 
      && isset($postValues['email']) //be sure to validate both!

  {
    if (isValidEmail($postValues['email'])) {
      subscribe($email);//this syntax may be off.

    } else {
      $returnMsg = "A valid email address must be provided.";
      return false;
    }
  } else {
    $returnMsg = "No subscription was attempted.";
    return false;
  }
}


//Returns true if the passed parameter is a valid email
static function isValidEmail($email) {
  //left as an exercise for the reader. 
}

//Assumes a valid email address is being passed
static function subscribe($email, &$returnMsg) {
  global $mysql; //sadly, this is the cleanest way possible without using a class.
  $stmt=$mysql->prepare($SQL_FIND_SUBSCRIPTION);
  $stmt->bind_param('s', $email);
  $stmt->execute();
  $stmt->store_result(); // This lets you reuse stmt

  if($stmt->field_count > 0){ 
    //Subscription already exists
    $returnMsg = "This subscription already exists.";
    return true;
  } else { 
    //Subscription must be added
    return addNewSubscription($email, $returnMsg);
  }
}

static function addNewSubscription($email, &$returnMsg) {
  global $mysql; // :(
  $stmt=$mysql->prepare($SQL_NEW_SUBSCRIPTION);
  $stmt->bind_param('s', $email);
  $stmt->execute();
  $stmt->store_result();

  if($stmt->affected_rows>0){
    $returnMsg = "New subscription successful!";
    return true;
  } else {
    $returnMsg = "New subscription failed.";//you can add more info here if you want
    return false;
  }

  $stmt->close();
}

//now actually execute
$resultMsg = "";
if (attemptSubscription($_POST, $resultMsg)) {
  echo "Success! ".$resultMsg;
} else {
  echo "Oh no! Failure! ".$resultMsg;
}



// ?> Note that eliding this will help remove nasty hidden characters from the rendered html