2014-09-05 95 views
1

我使用一个相当长的HTML表单来更新与产品相关的大量细节 - 为简洁起见,我不会共享整个表单。然而,为了说明的目的这里有一个片段:如何根据HTML中定义的变量动态生成MYSQL UPDATE语句FORM

HTML表单

<form name="form1" method="post" action="update_ac.php"> 
    <table width="100%" cellpadding="0" cellspacing="0"> 
    <tr> 
     <td> 
     <input name="season" type="text" class="button_select" id="season" value="<?=$rows['season']; ?>" size="10" /> 
     <input name="restock" type="checkbox" id="restock" value="on" <?php if($rows['restock']=='on') { echo 'checked="checked"'; } ?>/> 

     // other fields 

     </td> 
    </tr> 
    </table> 
</form> 

我的问题是发布形式update_ac.php的时候 - 我怎么能动态生成基于已完成的领域的MYSQL更新语句?

这里是我的表单操作页面的例子:

PHP表单操作

<?php 

     foreach ($_POST as $key => $value) { 
     $$key = $value; 
     } 

$sql= mysql_query (" 
UPDATE product SET 
title='".$title."', 
rating='".$rating."', 
season='".$season."', 
brand_id='".$brand_id."', 
category='".$category."', 

... etc "); 

?> 

我不希望要申报的每一个字段,它可能需要的UPDATE语句更新。我希望UPDATE语句只针对有关字段,因为从表单中发布已定义的PHP变量。

目前,我收到很多NOTICE: Undefined variable x,发布表单时已经有空字段。

我希望这是有道理的 - 有点啰嗦。

有什么建议吗?由于

UPDATE

从@ Styphon的答案继 - 我修改它稍微包括在查询结束时WHERE条件。

$query = "UPDATE product SET"; 
$comma = " "; 
foreach($_POST as $key => $val) { 
    if(! empty($val)) { 
     $query .= $comma . $key . " = '" . mysql_real_escape_string(trim($val)) . "'"; 
     $comma = ", "; 
    } 
} 

$product_id = $_POST['product_id']; 

$query = $query . "WHERE product_id = '".$product_id."' "; 
+0

查看'isset'也许> – Fluffeh 2014-09-05 10:29:04

+0

@Fluffeh - 这并不能解决我的问题,因为我不得不测试每个可能的变量对ISSET。我试图避免必须声明超过50个变量。 – aphextwix 2014-09-05 10:55:58

回答

3

假设表中的所有字段名称与表单输入的名称相同,这是直接的。您可以使用此:

$query = "UPDATE product SET"; 
$comma = " "; 
foreach($_POST as $key => $val) { 
    if(! empty($val)) { 
     $query .= $comma . $key . " = '" . mysql_real_escape_string(trim($val)) . "'"; 
     $comma = ", "; 
    } 
} 
$sql = mysql_query($query); 

为了更安全,你应该创建接受参数的白名单,即列在表中是这样的:

$query = "UPDATE product SET"; 
$comma = " "; 
$whitelist = array(
    'title', 
    'rating', 
    'season', 
    'brand_id', 
    'cateogry', 
    // ...etc 
); 
foreach($_POST as $key => $val) { 
    if(! empty($val) && in_array($key, $whitelist)) { 
     $query .= $comma . $key . " = '" . mysql_real_escape_string(trim($val)) . "'"; 
     $comma = ", "; 
    } 
} 
$sql = mysql_query($query); 

这样,你的查询只能包含参数你设置,如果有人管理注入额外(例如通过更改您的表单输入的名称)它不会被传递到您的数据库。


我也建议你停止使用Mysql_ *,这是deprecated。你应该看看MySQLiPDO作为替代。

+0

@nalply我已经在real_escape_string中添加了,现在也习惯于使用预准备语句。 – Styphon 2014-09-05 10:33:09

+0

@Styphon - 我刚刚意识到'WHERE product_id = $ product_id'行从语句结尾处缺少。我已经更新了上面的代码。谢谢 – aphextwix 2014-09-05 11:23:55

+0

@nalply我在查询周围使用了单引号,所以这是无关紧要的,该查询被保护。你在评论之前还看到了我的更新答案和白名单? – Styphon 2014-09-06 08:37:15