-1

I have a form set up on a users profile, so if they want to update items such as their first name, last name, username, or email then they can.

When they hit the submit on the form, a PHP script runs which essentially checks if any fields are not empty, and if there are not empty, run an update query to the db on the student table. However, nothing seems to be happening, wondering if someone could point out where I have gone wrong as the student table does not update?

profile.php:

<form action="scripts/update-profile.php" method="post">  
    <h3 class="left-align fontAmaticH1">Student Details</h3>
        <p class="left-align"><b>Username: </b><?php echo $row['username']; ?>
        <div class="update-profile"><input type="text" name="username" placeholder="Update Username..."></div>    
        </p>

        <p class="left-align"><b>Email Address: </b><?php echo $row['email']; ?>
        <div class="update-profile"><input type="text" name="email" placeholder="Update Email..."></div>
        </p>

        <p class="left-align"><b>First Name: </b><?php echo $row['firstName']; ?>
        <div class="update-profile"><input type="text" name="firstName" placeholder="Update First Name..."></div>
        </p>

        <p class="left-align"><b>Surname: </b><?php echo $row['lastName']; ?>
        <button name="update-details" class="update-details" type="submit">Update Details</button>
        </form>

Edit Details

PHP:

<?php
// Checking whether the user got to this page by clicking the proper button.
if (isset($_POST['update-details'])) {

      require 'db.php';

// We grab all the data which we passed from the update form
    $studentID = $_SESSION['studentID'];

    $username = $_POST['username'];
    $email = $_POST['email'];
    $profileImage = $_POST['profileImage'];
    $firstName = $_POST['firstName'];
    $lastName = $_POST['lastName'];


    $update = [];
    if (! empty($username)) {
        $update['username'] = "username ='".$username ."'";
    }

    if (! empty($email)) {
        $update['email'] = "email='".$email ."'";
    }

    if (! empty($firstName)) {
        $update['firstName'] = "firstName='".$firstName ."'";
    }

    if (! empty($lastName)) {
        $update['lastName'] = "lastName='".$lastName ."'";
    }


    if (! empty($update)) {
        $query = "UPDATE `student` SET ";
        $query .= implode(', ', $update);
        $query .= " WHERE `student`.`studentID` = $studentID ";
        $result = $conn->query($query) or die ("update SQL error");
    }


    header("Location: ../profile.php?update=success");
}

?>

STUDENT TABLE student Table

xo.
  • 485
  • 3
  • 10
  • Can you print $query above $result = $conn->query($query) or die ("update SQL error"); and check what query is being run ? Also why is this $result = $conn->query($query) or die ("update SQL error"); written twice ? – Mansi Mar 11 '20 at 12:16
  • 1
    You should learn to use parameterized queries. – sticky bit Mar 11 '20 at 12:46
  • You didn't name your submit button. What gets sent upon submit are names of the elements, you're testing against a class you have on the button. – El_Vanja Mar 11 '20 at 13:05
  • @El_Vanja I have added this in, can't believe I missed that. Still not working however. I have deleted the 2nd `$result` – xo. Mar 11 '20 at 18:38
  • @stickybit I do always use prepared statements however I'm not sure how it would be done with this style of update query as I'm trying to place them into an array, and only update the items which are not empty. – xo. Mar 11 '20 at 18:40
  • 1
    You are [**wide open for SQL injection**](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php) here. – Martin Mar 11 '20 at 18:43

1 Answers1

1

1:

You are wide open for SQL injection here. Use Parameterised Queries. ALWAYS.

2:

Check Your PHP Error logs

3:

Don't
Repeat
Yourself

Which means use PHP loop structures to save code and time and effort.

4:

Be aware that MySQL UTF-8 is NOT really UTF-8 and should always be replaced by utf8mb4_ character sets and collations.

5:

Your header Location redirects should always be followed by an exit/die() statement because PHP will keep processing until it reaches the end of the script, even if you give it a header. If you give multiple header "Location: ..."s then the final one is the one that will be followed.

6:

PHP has lots of array implosion and string interaction functions for you to use arrays in the context of turning them into Parameterised queries.

7:

Use Try / Catch blocks in PHP These should be used to catch errors and issues before they're committed.

8:

NEVER ever trust user input. Ever.


Quick and Dirty Example:

Using MySQLi ? syntax;

In your db.php file, to allow try/catch error catching with the MySQLi method:

    \mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);

In your script....

if (isset($_POST['update-details'])) { //tacky but it will do.

      require 'db.php';

    $studentID = (int)$_SESSION['studentID']; 
                  // force to type integer to ensure 
                  // data is always valid.

    unset($_POST['update-details']); // forget this value. 
    $update = []; // make a new array
    // Because your array keys are the same, you can simply loop through 
    // checking and then adding from one array to another. 
    // 
    // alternatively you can copy the whole @_POST array and simply 
    // run `array_filter` on it to clean it of empty values. 
    // (but this will not catch whitespaces)
    foreach($_POST as $key=>$data){
          $data = trim($data);
          if(!empty($data)){
             // use REGEX to do some cleaning of your Key values. 
             // NEVER EVER trust user input. NEVER. 
             $key = preg_replace("/[^a-z]/i","",$key);
             $update[$key] = $data;
          }
    }
    // end foreach. 
    if (\count($update) > 0 ) {
        $keyString = implode(" = ? ,",array_keys($update));
        $keyString." = ?" //append last reference

        // Now build the dynamically built Parameterised SQL:
        $query = "UPDATE `student` SET ".$keyString." WHERE `student`.`studentID` = ? ";
        
        $runQuery = $conn->prepare($query);

        // We will assume here all your data is a string (s) type. 

        $dataType = str_repeat("s", count($update));
        $dataType .= "i"; // append data type for the ID at the end. 
        $update[] = $studentID;
        

        //Use a Try / Catch block to check the functions work correctly. 
        // you can also use SQL transactions. 
        try {
            // Bind your data to your query object
            $runQuery->bind_param($dataType, \implode(",",$update));
            // Execute your query.
            $runQuery->execute(); 
            $runQuery->free_result();
           
            // This can feedback the number of rows updated. 
            $rows = (string)$runQuery->affected_rows;
            error_log("Rows updated: ".$rows);
           
            //close your query. 
            $runQuery->close();
        }
        catch(\mysqli_sql_exception $ex) {
             // Do something with your query failure. 
             error_log("MySQL Error!: ".print_r($ex,true));
         } 
    } //end count update

    header("Location: ../profile.php?update=success");
    exit; // STOP further PHP execution. 
}
Community
  • 1
  • 1
Martin
  • 22,212
  • 11
  • 70
  • 132