如何只更新PHP表单中给定元组的一个属性?

如何只更新PHP表单中给定元组的一个属性?,php,html,mysql,Php,Html,Mysql,我已经用PHP创建了一个更新表单,它采用元组的属性。以下查询根据输入更新表的元组: <?php error_reporting(E_ALL); ini_set('display_errors', 1); if(isset($_POST['submit'])) { $sql = "UPDATE member SET MFirst='".$_POST["MFirst"]."', MLast='".$_POST["MLast"]."',Street='".$_

我已经用PHP创建了一个更新表单,它采用元组的属性。以下查询根据输入更新表的元组:

<?php
    error_reporting(E_ALL); ini_set('display_errors', 1);

    if(isset($_POST['submit'])) {

        $sql = "UPDATE member SET MFirst='".$_POST["MFirst"]."', MLast='".$_POST["MLast"]."',Street='".$_POST["Street"]."'
            ,number='".$_POST["number"]."',postalCode='".$_POST["postalCode"]."',Mbirthdate='".$_POST["Mbirthdate"]."' 
            WHERE memberID='".$_POST["memberID"]."'";

        $result = mysqli_query($conn,$sql);
    }
?>   

通过迭代$\u POST并将其相应地添加到“SET”列表中,可以省略任何空的或未提交的列。然而,这是危险的,因为你永远不应该相信从互联网收到的任何信息。(见附件)

下面的代码在使用mysqli时可以满足您的需要,这可以降低SQL注入风险。它还验证$\u POST键是否为有效的表列名

评论中有解释:

<?php
if (isset($_POST['submit'])) {

// Assume $_POST is in this format:
// $_POST = [ "MFirst" => "John", "MLast" => "Doe", "Street" => "Infinity Loop", "number" => 1, "postalCode" => 95014, "Mbirthdate" => "01-01-1990", "memberId" => "abcde-1", "submit" => 1];

// remove $_POST elements not part of SET list
    $_POST = array_filter($_POST); //remove any empty elements
    unset($_POST["submit"]);
    $member_id = $_POST["memberId"];
    unset($_POST["memberId"]);

//stop now if form is empty
    if (count($_POST) == 0) exit(); 

// array of valid columns as keys, and their types as values (s = string, i = integer)
    $member_col_types = [ "MFirst"     => "s",
                          "MLast"      => "s",
                          "Street"     => "s",
                          "number"     => "i",
                          "postalCode" => "i",
                          "Mbirthdate" => "s",
                          "memberId"   => "s"
    ];

    $key_val = [];
    $types   = "";
    $columns = array_keys($member_col_types);
    $values  = [];

    foreach ($_POST as $k => $v) {
// ensure all inputs are valid table columns, otherwise exit
        if (in_array($k, $columns) == false) {
            exit("");
        }
// dynamically adding only valid $_POST
        $key_val[] = "$k=?"; // [ "MFirst=?","MLast=?",...]
// grabs values to be inserted into ?
        $values[] = $v; //["John","Doe","Infinity Loop",1,95014,"01-01-1990"]
// grabs the variable types for binding values above to types like string, integer
        $types .= $member_col_types[ $k ]; // "sssiis"
    }

    $list = implode(", ", $key_val);

// add binding and value for memberId (part of WHERE) not processed in loop above
    $values[] = $member_id; //["John","Doe","Infinity Loop",1,95014,"01-01-1990","abcde-1"]
    $types    .= "s"; // "sssiiss"

    $sql = "UPDATE member SET $list WHERE memberId=?"; 
    //UPDATE member SET MFirst=?, MLast=?, Street=?, number=?, postalCode=?, Mbirthdate=? WHERE memberId=?

// prepare the query (assuming mysqli connection $conn)
    $stmt = $conn->prepare($sql) or die($conn->error);

// bind the values to their types
    $stmt->bind_param($types, ...$values) or die($conn->error);
    $stmt->execute() or die($stmt->error);

}

通过迭代$\u POST并将其相应地添加到“SET”列表中,可以省略任何空的或未提交的列。然而,这是危险的,因为你永远不应该相信从互联网收到的任何信息。(见附件)

下面的代码在使用mysqli时可以满足您的需要,这可以降低SQL注入风险。它还验证$\u POST键是否为有效的表列名

评论中有解释:

<?php
if (isset($_POST['submit'])) {

// Assume $_POST is in this format:
// $_POST = [ "MFirst" => "John", "MLast" => "Doe", "Street" => "Infinity Loop", "number" => 1, "postalCode" => 95014, "Mbirthdate" => "01-01-1990", "memberId" => "abcde-1", "submit" => 1];

// remove $_POST elements not part of SET list
    $_POST = array_filter($_POST); //remove any empty elements
    unset($_POST["submit"]);
    $member_id = $_POST["memberId"];
    unset($_POST["memberId"]);

//stop now if form is empty
    if (count($_POST) == 0) exit(); 

// array of valid columns as keys, and their types as values (s = string, i = integer)
    $member_col_types = [ "MFirst"     => "s",
                          "MLast"      => "s",
                          "Street"     => "s",
                          "number"     => "i",
                          "postalCode" => "i",
                          "Mbirthdate" => "s",
                          "memberId"   => "s"
    ];

    $key_val = [];
    $types   = "";
    $columns = array_keys($member_col_types);
    $values  = [];

    foreach ($_POST as $k => $v) {
// ensure all inputs are valid table columns, otherwise exit
        if (in_array($k, $columns) == false) {
            exit("");
        }
// dynamically adding only valid $_POST
        $key_val[] = "$k=?"; // [ "MFirst=?","MLast=?",...]
// grabs values to be inserted into ?
        $values[] = $v; //["John","Doe","Infinity Loop",1,95014,"01-01-1990"]
// grabs the variable types for binding values above to types like string, integer
        $types .= $member_col_types[ $k ]; // "sssiis"
    }

    $list = implode(", ", $key_val);

// add binding and value for memberId (part of WHERE) not processed in loop above
    $values[] = $member_id; //["John","Doe","Infinity Loop",1,95014,"01-01-1990","abcde-1"]
    $types    .= "s"; // "sssiiss"

    $sql = "UPDATE member SET $list WHERE memberId=?"; 
    //UPDATE member SET MFirst=?, MLast=?, Street=?, number=?, postalCode=?, Mbirthdate=? WHERE memberId=?

// prepare the query (assuming mysqli connection $conn)
    $stmt = $conn->prepare($sql) or die($conn->error);

// bind the values to their types
    $stmt->bind_param($types, ...$values) or die($conn->error);
    $stmt->execute() or die($stmt->error);

}

您应该了解SQL注入,但无论如何,您可以使用三元运算符来使用post值(如果已定义)或默认值,例如:$\u post[“memberID”]$_POST[“memberID”]:“@DylanKas我应该把它放在哪里?”,因为我是这样写的:SET MFirst='“$\u POST[“MFirst”]?”,它不接受它的工作原理,基本上只是一个If/Else语句:@DylanKas如果我使用默认的空值,元组会将它改为空值,任何未键入的内容我都希望它保持在元组上的状态,然后也包括你的集合,比如$\u POST[“memberID”] ? “”SET MFirst='.$\u POST[“memberID”]。“:”“您应该阅读有关SQL注入的内容,但无论如何,您可以使用三元运算符来使用POST值(如果已定义)或默认值,例如:$\u POST[“memberID”]$_POST[“memberID”]:“@DylanKas我应该把它放在哪里?”,因为我是这样写的:SET MFirst='“$\u POST[“MFirst”]?”,它不接受它的工作原理,基本上只是一个If/Else语句:@DylanKas如果我使用默认的空值,元组会将它改为空值,任何未键入的内容我都希望它保持在元组上的状态,然后也包括你的集合,比如$\u POST[“memberID”] ? “”设置MFirst='。$\u POST[“memberID”]。':“”