在PHP中向MySQL插入多行(单个查询):Prepare-Execute与Prepare-Bind-Execute

时间:2015-05-04 18:55:41

标签: php mysql pdo prepared-statement prepare

我正在编写一些PHP来接受 POST 中的数字和名称数组,并将它们插入到MySQL表中(名为 Contacts_table 这里的版本工作正常,没有任何错误:

<?php

  // Includes
  require_once 'Admin/Connector.php';

  // Test if payload exists
  if($_POST){

  // Read payload into arrays
      $ar = 0;
      foreach($_POST as $entry){
          $namenum = explode(',', $entry);
          $names[$ar] = $namenum[1];
          $numbers[$ar] = $namenum[0];
          $ar += 1;
      }
      $namenum = NULL;

  // Build SQL query
      $sql = 'INSERT INTO Contact_table (NAME, PHONE) VALUES ';
      $insertQuery = array();
      $insertData = array();
      $n = 0;
      foreach ($numbers as $num) {
        $insertQuery[] = '(?, ?)';
        $insertData[] = $names[$n];
        $insertData[] = $num;
        $n++;
      }
      $sql .= implode(', ', $insertQuery);
      $sql .= ' ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name), name);';
      $n = NULL;
      $num = NULL;

  // Connect to MySQL database
      $connect = dbconn(PROJHOST,PROJDB,PROJDBUSER,PROJDBPWD);

  // Execute SQL query
      $query = $connect->prepare($sql);
      $query->execute($insertData);
      $insertQuery = NULL;
      $insertData = NULL;
      $sql = NULL;
      $query = NULL;

  // Close connection to MySQL database
      $connect = NULL;

  }

?>

但是,正如您所看到的,我在这里没有使用 bindParam()函数,只是将值直接提供给 execute()函数。许多人建议我使用 bindParam()代替服务器性能提升。它是真的还是我现在更喜欢这个项目?我尝试使用bindParam编写并运行上述代码的版本:

<?php

  // Includes
  require_once 'Admin/Connector.php';

  // Test if payload exists
  if($_POST){

  // Read payload into arrays
      $ar = 0;
      foreach($_POST as $entry){
          $namenum = explode(',', $entry);
          $names[$ar] = $namenum[1];
          $numbers[$ar] = $namenum[0];
          $ar += 1;
      }
      $namenum = NULL;

  // Build SQL query
      $sql = 'INSERT INTO Contact_table (NAME, PHONE) VALUES ';
      $insertQuery = array();
      $insertData = array();
      $n = 0;
      foreach ($numbers as $num) {
        $insertQuery[] = '(?, ?)';
        $insertData[] = $names[$n];
        $insertData[] = $num;
        $n++;
      }
      $sql .= implode(', ', $insertQuery);
      $sql .= ' ON DUPLICATE KEY UPDATE name = COALESCE(VALUES(name), name);';
      $n = NULL;
      $num = NULL;

  // Connect to MySQL database
      $connect = dbconn(PROJHOST,PROJDB,PROJDBUSER,PROJDBPWD);

   // Prepare SQL query 
      $query = $connect->prepare($sql);

  // Bind variables
      foreach($insertData as $key => &$ins) {
          $connect->bindParam($key+1,$ins);
      }

  // Execute SQL query
      $query->execute();
      $insertQuery = NULL;
      $insertData = NULL;
      $sql = NULL;
      $query = NULL;
      $key = NULL;
      $ins = NULL;

  // Close connection to MySQL database
      $connect = NULL;

  }

?>

但是这段代码拒绝运行并返回致命错误 - 调用未定义的方法PDO :: bindParam() 。我在这做错了什么?我理解,如果我在循环中包含 execute(),那么编写一个更简单的代码是可能的,但这会产生多个我想要不惜一切代价避免的查询。无论如何,我的目标都是单一查询。

1 个答案:

答案 0 :(得分:1)

你不能$connect->bindParam($key+1,$ins);。因为PDO对象没有这样的方法。只有PDOStatement有。这就是为什么你有错误信息。

你应该:

 $query->bindValue($key+1,$ins);

您应该使用bindValue,因为如果没有,所有插入的值都会得到相同的值(在您调用execute之前,$ ins中的最后一个值)。