【问题标题】:dynamic prepared insert statement动态准备好的插入语句
【发布时间】:2015-05-20 19:36:06
【问题描述】:

让我先说一下,我刚刚开始学习准备好的陈述,其中很多内容可能难以掌握,但我想尝试一下。

我正在尝试在我的 DatabaseObject 类中创建一个动态创建函数。该函数将采用可能任意数量的不同允许数据类型的任意数量的值。不幸的是,我尝试过的任何事情都没有奏效。这是代码。

public function create() {
    $db = Database::getInstance();
    $mysqli = $db->getConnection();
    //array of escaped values of all types in the object
    $attributes = $this->sanitized_attributes();

    $check = $mysqli->stmt_init();

    $paramType = array();

    $types = ''; $bindParam = array(); $where = ''; $count = 0;

    foreach($attributes as $key=>$val)
    {
        $types .= 'i';
        $bindParam[] = '$p'.$count.'=$param["'.$key.'"]'; 
        $where .= "$key = ? AND ";
        $count++;
    }

    $sql_query = "INSERT INTO `".static::$table_name."` ";  

    $sql_query .= "VALUES (";

    foreach ($attributes as $key => $value) {
        $valueType = gettype($value);

        if ($valueType == 'string') {
            $sql_query .= "?,";
            array_push($paramType, "s");
        } else if ($valueType == 'integer') {
            $sql_query .= "?,";
            array_push($paramType, "i");
        } else if ($valueType == 'double') {
            $sql_query .= "?,";
            array_push($paramType, "d");
        } else {
            $sql_query .= "?,";
            array_push($paramType, "b");
        }           
    }

    $sql_query .= ")";
}

在这一点上,我完全不知道我应该做什么。

我已经得到了简单的准备好的语句,但是这个更复杂和动态,我不知道我是否正确地处理了这个过程,以及在 sql_query 之后做什么才能得到这个工作。这里的所有问题都让我感到困惑,所以如果我得到有关我当前代码的指导,看看我哪里出错了,它会有所帮助。

感谢您的宝贵时间。

【问题讨论】:

    标签: php mysqli prepared-statement


    【解决方案1】:
    public function create() {
        $db = Database::getInstance();
        $mysqli = $db->getConnection();
    
        $attributes = $this->sanitized_attributes();
    
        $tableName = static::$table_name;
    
        $columnNames = array();
        $placeHolders = array();
        $values = array();
    
        foreach($attributes as $key=>$val)
        {
            // skip identity field
            if ($key == static::$identity)
                continue;
            $columnNames[] = '`' . $key. '`';
            $placeHolders[] = '?';
            $values[] = $val;
        }
    
        $sql = "Insert into `{$tableName}` (" . join(',', $columnNames) . ") VALUES (" . join(',', $placeHolders) . ")";
    
        $statement = $mysqli->stmt_init();
        if (!$statement->prepare($sql)) {
            die("Error message: " . $mysqli->error);
            return;
        }
    
        $bindString = array();
        $bindValues = array();
    
        // build bind mapping (ssdib) as an array
        foreach($values as $value) {
            $valueType = gettype($value);
    
            if ($valueType == 'string') {
                $bindString[] = 's';
            } else if ($valueType == 'integer') {
                $bindString[] = 'i';
            } else if ($valueType == 'double') {
                $bindString[] = 'd';
            } else {
                $bindString[] = 'b';
            }
    
            $bindValues[] = $value;
        }
    
        // prepend the bind mapping (ssdib) to the beginning of the array
        array_unshift($bindValues, join('', $bindString));
    
        // convert the array to an array of references
        $bindReferences = array();
        foreach($bindValues as $k => $v) {
            $bindReferences[$k] = &$bindValues[$k];
        }
    
        // call the bind_param function passing the array of referenced values
        call_user_func_array(array($statement, "bind_param"), $bindReferences);
    
        $statement->execute();  
        $statement->close();
    
        return true;
    }
    

    我想特别说明一下,我自己没有找到解决方案。我有很长时间的开发人员找到了这个解决方案,并想把它发布给那些可能想知道的人。

    【讨论】:

      【解决方案2】:

      我在尝试自己寻找完全相同的问题的解决方案时偶然发现了您的旧帖子。我的代码似乎更有优势,因为只包含一个循环。因此,我会将它作为可能的改进添加到这篇文章中:

          $sqlquery = $this->MySQLiObj->prepare($dummy);
      
          $paramQuery = array();
          $paramQuery[0] = '';
      
          $n = count($valueArray);
          for($i = 0; $i < $n; $i++) {
              $checkedDataType = $this->returnDataType($valueArray[$i]);
              if($checkedkDataType==false) {
                  return false;
              }
              $paramQuery[0] .= $checkedDataType;
              /* with call_user_func_array, array params must be passed by reference -> & */
          $paramQuery[] = &$valueArray[$i];
          }
      
          /*In array(): sqlquery(object)->bind_param(method)*/
          call_user_func_array(array($sqlquery, 'bind_param'), $paramQuery);
          $sqlquery->execute();
          /*Can be used identical to $result = $mysqli->query()*/
          $result = $this->MySQLiObj->get_result();
          $sqlquery->close();
      

      将函数 returnDataType() 与 switch 语句结合使用,如果偏好某种数据类型,这可能会更快。

          private function returnDataType($input) {
          switch(gettype($input)) {
              case string: return 's';
              case double: return 'd';
              case integer: return 'i';
              default: $this->LOG->doLog("Unknown datatype during database access."); return 's';
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2015-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-03-05
        相关资源
        最近更新 更多