【问题标题】:PDO insert based on array keys as column names基于数组键作为列名的 PDO 插入
【发布时间】:2016-01-05 08:26:44
【问题描述】:

我有一个 PDO 插入语句,它通过表单提交更新数据库表。有很多领域。我特意使用了与 html 输入名称相同的列名称。有没有更简洁的方式来布置这段代码?目前我有 30 多个 $_POST 变量,并且希望通过某种循环获得更简洁的解决方案。

这是我当前的实现,为了举例,我只包含了几个字段。

$stmt = $dbh->prepare("INSERT INTO myTable SET Col1 = ?, ColABC = ?, Col123 = ?, ColFoo = ?, ColDEF = ?");
$stmt->execute(
    array($_POST['Col1'], $_POST['ColABC'], $_POST['Col123'], $_POST['ColFoo'], $_POST['ColDEF'])
);

【问题讨论】:

    标签: php pdo


    【解决方案1】:

    试试下面的方法

    $postarr = array('Col1', 'ColABC', 'Col123', 'ColFoo', 'ColDEF'); //<---- defined all the form elements you like to get from post
    $sql = ''; $param = array();
    foreach($postarr as $k){
        $sql .= $k.'=:'.$k.','; // setting up placeholders for columns we are goign to update or get value from $_POST data
        $param[$k] = $_POST[$k]; // setting up param array argument for execute() function
    }
    $sql = substr($sql,0,-1); // <--- remove last ,
    $stmt = $dbh->prepare("INSERT INTO myTable SET " . $sql);
    $stmt->execute($param);
    

    【讨论】:

    • 这不会转义后变量,因此可能会使数据库对 SQL 注入开放
    • 多一点解释会对 OP 有所帮助
    • @steve 我没有直接在insert 语句中分配值,而使用占位符并且实际值在execute 函数中作为数组发送。希望它能支持 SQL 注入
    【解决方案2】:

    以下内容未经测试,但您或许可以尝试类似的方法。

    <form id='sqlpost' method='post' action='/test/target.php'>
        <h1>SQL Post</h1>       
        <input type='text' name='user' value='fred'/>
        <input type='text' name='name' value='frederick'/>
        <input type='text' name='email' value='fred@bedrock.com'/>
    
        <input type='text' name='age' value='21'/>
        <input type='text' name='sex' value='male'/>
    
        <input type="submit" name="subform" value="Submit"/>
    </form>
    
    
    /*
    target.php
    ----------
    */
    
    if( $_SERVER['REQUEST_METHOD']=='POST' ){
    
        $known=array('user','email','name');
        $postdata=array();
    
    
        foreach( $_POST as $field => $value ){
            if( in_array( $field, $known ) ) $postdata[ $field ]=$value;
        }
    
        $keys=array_keys( $postdata );
        $values=array_values( $postdata );              
    
        $sql='insert into myTable (`'.implode('`,`',$keys).'`) values (:'.implode(':',$keys).')';
        echo $sql;
    }
    

    【讨论】:

    • 如果该列不存在,这可能会出错吗?
    • 是的 - 最好的办法是拥有一个已知字段名称的数组,并在 POST 数组上使用 array_intersect 之类的东西来确保字段存在
    • 谢谢,这样可以。由于未使用绑定方法,此解决方案是否可以防止 SQL 注入?
    • 一个稍微不同的版本来解决您对不存在字段的担忧 ~ 使用“已知”字段数组并忽略那些不在该已知字段数组中的字段。
    【解决方案3】:

    将所有值放入数组 $input。并使用 list() 如下。

    $InputArray['cal1'] =  $_POST['cal1'];
    $InputArray['collabc'] =  $_POST['collabc'];
    $InputArray['col123'] =  $_POST['col123'];
    $InputArray['clofoo'] =  $_POST['clofoo'];
    $InputArray['coldef'] =  $_POST['coldef'];
    
    if (count($inputArray) > 0) {
            while (list($key, $val) = each($inputArray)) {
                if(!empty($val)){
                    $fields.= $key . ',';
                    $valset.= "'". $val ."',";
                }
            }
        }   
    
        $fields = trim($fields, ',');
        $valset = trim($valset, ',');
        $sql = "INSERT INTO $tableName ($fields) VALUES ($valset)";
    
        $stmt = $this->dbCon->prepare($sql);
        $stmt->execute($inputArray);
    

    【讨论】:

      猜你喜欢
      • 2012-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-01
      • 1970-01-01
      • 2016-12-14
      相关资源
      最近更新 更多