2017-07-18 63 views
5

嗨,作为标题状态,我正在寻找一种方法来动态查询我的MySQL服务器。目前,这是我用在服务器上更新数据的代码:使用PHP动态查询MySQL

$deskAttr = json_decode($_POST["desk_attributes"]); 

foreach($deskAttr as $key => $value) { 
    $sql = "UPDATE desk_attributes SET iw_standard=".$value->iw_standard.", avaya_standard=".$value->avaya_standard.", avaya_withcallid=".$value->avaya_withcallid.", avaya_withtransfer=".$value->avaya_withtransfer.", dual_screen=".$value->dual_screen.", air_conditioning=".$value->air_conditioning.", iw_obdialler=".$value->iw_obdialler." WHERE id=".$value->id; 
    $conn->query($sql); 
} 

正如你所看到的,SQL列名是一样的deskAttr键。我正在寻找一种方法让这一行成为一个循环,这样我就不需要改变这一行,如果我要添加更多的列到MySQL表中。

这将是这个样子:

$deskAttr = json_decode($_POST["desk_attributes"]); 

foreach($deskAttr as $key => $value) { 
    $sql = "UPDATE desk_attributes SET"; 
    foreach($value as $k => $v) { 
     $sql .= " $k = $value->$k ,"; 
    } 
    $sql .= "WHERE id=".$value->id"; 
} 

我怎么会写上面的代码,以便它会实际工作? 谢谢。


编辑

也许这将有助于知道$deskAttr是对象数组和列的名称是一样的对象键的名称。

这里是我的意思是伪代码:

foreach($object in $deskAttr) { 
    $sql = "UPDATE table SET "; 
    foreach($key in $object) { 
     if($key != "id") 
      $sql .= "$key = $object->$key, "; 
    } 
    $sql .= "WHERE id = $object->id; 
    $conn->query($sql); 
} 

显然,这将在WHERE部分查询之前的末尾添加一个额外的逗号,但希望你明白我想要的目的。

+1

您是大开[SQL注入(http://php.net/manual/en/security.database.sql-injection.php)和确实应该使用[Prepared Statements](准备好的语句)(http://php.net/manual/en/mysqli.quickstart.prepared-statements.php),而不是串联你的查询。特别是因为你没有逃避用户输入! –

+1

你应该真的切换到准备好的语句的值和列名的白名单,以避免SQL注入。 – jeroen

+0

您无法通过预准备语句绑定列名称。所以,如果你要在你的SQL查询字符串中放置一个可变字符串,那么正确地转义它们并且你没事。 –

回答

1

您可以使用PHP的implode()函数对代码进行轻微更改。

取一个空白数组,连接更新参数。

然后如果不是empty(),implode()得到字符串。

更新的代码:

$sql = "UPDATE desk_attributes SET "; 
foreach ($deskAttr as $key => $value) { 
$value = mysqli_real_escape_string($link, $value); // $links is database connection string. 
$key = mysqli_real_escape_string($link, $key); // $links is database connection string. 
$updtAttrs[] = $key ." = '" . $value . "'"; 
} 
$sql .= ! empty($updtAttrs) ? implode(', ', $updtAttrs) : ''; 
$sql .= " WHERE id=" . $value->id; 
+2

此代码** **非常不安全。它对SQl注射开放很大。您应该使用Prepared Statements,而不是像这样直接连接用户输入。您还应该有一个允许的列名称列表。 –

+0

不,不是。不要成为准备好声明纳粹,并阅读'mysqli_real_escape_string'文档 –

+0

@KiJéy - 也许你应该检查评论的时间线和帖子的编辑。 ** 1。**当我写评论时,'mysqli_real_escape_string()'不包含在答案_at all_中。 ** 2。'$ key'完全未转义,_still_使SQL注入100%打开。顺便说一句,实际上有'mysqli_real_escape_string()'是不够的情况下:https://stackoverflow.com/questions/5741187/sql-injection-that-gets-around-mysql-real-escape-string/12118602#12118602 –