dynamic prepared insert statement

前端 未结 2 484
孤独总比滥情好
孤独总比滥情好 2021-01-17 01:18

Let me preface that I just started learning prepared statements so much of this might just be to much to grasp, but I want to try.

I am trying to make a dynamic crea

相关标签:
2条回答
  • 2021-01-17 01:35
    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;
    }
    

    I want to make special note that I did not find the solution myself. I had a long time developer find this solution and wanted to post it for those that might want to know.

    0 讨论(0)
  • 2021-01-17 01:48

    I accidently found your old post as I was trying myself to find a solution to the exact same problem. My code seems a bit more advantagous as there is only one loop included. Therefore I will add it as a possible improvement to this post:

        $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();
    

    Utilizing the function returnDataType() with a switch statement, which might be faster if there is a preference for a certain data type.

        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';
        }
    }
    
    0 讨论(0)
提交回复
热议问题