0

I have a form that echoes values for a specific user from a MySQL database using PHP. I am trying to figure out how to allow the user to submit the form to update their user information but have the form skip any field they have no filled out.

Current update statement

if (!isset($_POST['btnLogin'])) {
    $db = DB();
    $stmt = "UPDATE users SET fName = :fName, 
                              lName = :lName, 
                              emailAddress = :emailAddress 
                              WHERE user_id = $user->user_id";
    $query = $db->prepare($stmt);
    $query->bindParam(':fName', $_POST['fName'], PDO::PARAM_STR);
    $query->bindParam(':lName', $_POST['lName'], PDO::PARAM_STR);
    $query->bindParam(':emailAddress', $_POST['emailAddress'], PDO::PARAM_STR);
    $query->execute();
};

Form echoing user information

<form class="form-horizontal" action="profile.php" method="post">
                <div class="form-group">
                    <label class="col-lg-3 control-label">First name:</label>
                    <div class="col-lg-8">
                        <input class="form-control" type="text" name="fName" placeholder="<?php echo $user->fName ?>"/>
                    </div>
                </div>
                <div class="form-group">
                    <label class="col-lg-3 control-label">Last name:</label>
                    <div class="col-lg-8">
                        <input class="form-control" type="text" name="lName" placeholder="<?php echo $user->lName ?>">
                    </div>
                </div>
                <div class="form-group">
                    <label class="col-lg-3 control-label">Email:</label>
                    <div class="col-lg-8">
                        <input class="form-control" type="email" name="emailAddress" placeholder="<?php echo $user->emailAddress?>">
                    </div>
                </div>
                <div class="form-group">
                    <label class="col-md-3 control-label">Username:</label>
                    <div class="col-md-8" style="margin-top: 7px;">
                        <?php echo $user->username ?>
                    </div>
                </div>
                <div class="form-group">
                    <label class="col-md-3 control-label"></label>
                    <div class="col-md-8">
                        <input class="btn btn-primary" name="btnUpdate" value="Save Changes" type="button">
                        <span></span>
                        <input class="btn btn-default" value="Cancel" type="reset">
                    </div>
                </div>
            </form>

Currently this doesnt appear to update the database at all. If I leave the form completely blank and submit it, the values that existed in the database are now empty. i.e., just blank columns.

I have been looking at other examples on how to do this but I cannot seem to figure this out. Any help would be appreciated.

Just to be sure I am in fact updating the correct user, I made sure that my $user->user_id statement is in fact returning the correct user_id from the database for the update.

UPDATE

Currently this is how I have the update statement / code

if(!empty(['btnUpdate'])) {
$stmt = "UPDATE users SET fName = IF(:fName = '', fName, :fName), 
                lName = IF(:lName = '', lName, :lName), 
                emailAddress = IF(:emailAddress = '', emailAddress, :emailAddress)
        WHERE user_id = $user->user_id";
$db = DB();
$query = $db->prepare($stmt);
$query->bindParam("fName", $fName, PDO::PARAM_STR);
$query->bindParam("lName", $lName, PDO::PARAM_STR);
$query->bindParam("emailAddress", $emailAddress, PDO::PARAM_STR);
$query->execute();
}

Using <?php var_dump($_POST) ?> returns 0 after submitting the form and I still end up with empty database columns

Marty Lavender
  • 105
  • 1
  • 12
  • 3
    `$_POST['$fName']` is a typo on the name. You also should bind the `$user->user_id`. If `$fName` is set that should be unquoted or in double quotes. – chris85 Aug 02 '17 at 21:15
  • Im not sure I completely understand your comment. I see the typo on the fName. If I am simply grabbing the user_id and not submitting it, should I need to bind it? – Marty Lavender Aug 02 '17 at 21:21
  • There are other typos in your code, too: your named placeholders, when used in `bindParam()`, must have a `:` at the start, i.e. `$query->bindParam(':lName'...)`. The way you are referencing objects in your `$_POST` object is also incorrect: `$_POST['$fName']` should be `$_POST['fName']` instead, for example. – Terry Aug 02 '17 at 21:22
  • @Terry it's not necessary any more. – Paul Spiegel Aug 02 '17 at 21:23
  • I have updated the OP. Outside of this however, what logic would you use in PHP to ignore blank fields so the columns arent updated? – Marty Lavender Aug 02 '17 at 21:26
  • @PaulSpiegel It is not officially documented, so I would say we go on the safe side: https://stackoverflow.com/questions/9778887/is-the-leading-colon-for-parameter-names-passed-to-pdostatementbindparam-opt. – Terry Aug 02 '17 at 21:40
  • 3
    You will need to build the query dynamically. Use the `empty` function (unless `0` is a valid value for some of your fields). You should bind everywhere, don't put variables in queries. – chris85 Aug 02 '17 at 21:40
  • @Terry/Paul For `:` or not topic see: https://stackoverflow.com/questions/17386469/pdo-prepared-statement-what-are-colons-in-parameter-names-used-for. – chris85 Aug 02 '17 at 21:42

2 Answers2

3

This isn't ignoring empty fields, but a more user friendly solution would be to stick the database values into each input's value attribute. That way, you don't have to skip the fields if they're blank, and a user won't get confused when editing their data. If you don't want them to be able to edit the value, just include the readonly attribute.

If you don't want to do this, than you could either create a dynamic query or use an if statement to decide which value to use, the form's or the database's.

Blaise
  • 330
  • 1
  • 11
1

You can make the query check whether the value is empty, and reuse the existing value.

$stmt = "UPDATE users SET fName = IF(:fName = '', fName, :fName), 
                          lName = IF(:lName = '', lName, :lName), 
                          emailAddress = IF(:emailAddress = '', emailAddress, :emailAddress)
                          WHERE user_id = $user->user_id";

You could also build the query and parameters dynamically.

$sets = array();
$params = array();
foreach (array('fName', 'lName', 'emailAddress') as $field) {
    if (!empty($_POST[$field])) {
        $sets[] = "$field = :$field";
        $params[":$field"] = $_POST['field'];
    }
}
if (!empty($sets)) {
    $sets_string = implode(', ', $sets)
    $stmt = "UPDATE users SET $sets_string WHERE user_id = :id";
    $params[":id"] = $user->user_id;
    $query = $db->prepare($stmt);
    $query->execute($params);
}
Barmar
  • 741,623
  • 53
  • 500
  • 612