Skip to content

Student Listing - Edit a Student Page

Before we create our editstudent.php script, let's first add a navigation link for editing a student to our Student Details page studentdetails.php script. Open up the studentdetails.php script and add the following horizontal line and navigation link just below the closing table tag </table> line:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
...
</table>
<hr/>
<p>If you would like to change any of the details of this student,feel free to 
  <a href='editstudent.php?id_to_edit=<?=$row['id']?>'> edit it</a></p>
    <?php
        else:
    ?>
<h3>No Student Details :-(</h3>
  ...

Creating a Edit a Student Page with the Usual Bootstrap Template with a Card

Let's create a editstudent.php script using a Bootstrap template and add a Card for our content with a header for the title of the page:

editstudent.php - Edit Student: using Bootstrap Template with Card

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<html>
  <head>
    <link rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
          integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
          crossorigin="anonymous">
    <title>Edit Student</title>
  </head>
  <body>
    <div class="card">
      <div class="card-body">
        <h1>Edit a Student</h1>
      </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
            integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
            crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"
            integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
            crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"
            integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k"
            crossorigin="anonymous"></script>
  </body>
</html>

Connect to the Student Database

We'll need to access the Student database for the student we want to edit:

editstudent.php - Edit Student: Connect to the Database

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<body>
<div class="card">
    <div class="card-body">
    <h1>Edit a Student</h1>
    <?php
        require_once('dbconnection.php');

        $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
                or trigger_error('Error connecting to MySQL server for DB_NAME.',
                        E_USER_ERROR);

Multiple Ways to Navigate to Edit a Student Page

There are two expected ways and various unanticipated ways to navigate to the editstudent.php script.

The first expected way is for the user to select the edit it link on the Student Details page. Doing so sends a single query parameter contained in the id_to_edit element of the $_GET super global variable.

The second expected way is when the user selects Update Student. When the user successfully enters the required data in the form fields and submits the form, we will want to update the data for this student in the studentListing table of the Student database. You can find the submitted form fields in the $_POST super global variable.

All other mechanisms are unanticipated. So this essentially gives us three choices we are looking for. Therefore, the best way to deal with these three choices is to create an if/elseif/else block of code structure:

editstudent.php - Edit Student: Conditions for Navigating to this Page

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
    $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
            or trigger_error('Error connecting to MySQL server for DB_NAME.',
                    E_USER_ERROR);

    if (isset($_GET['id_to_edit']))
    {
        ...
    }
    elseif (isset($_POST['edit_student_submission'], $_POST['student_first_name'],
                  $_POST['student_last_name'], $_POST['student_email']))
    {
        ...
    }
    else // Unintended page link
    {
        ...
    }
?>

Direct Navigation from Student Details

The first intended way we will navigate to the editstudent.php script is when the user selects the edit it link on the studentdetails.php page. The link causes an HTTP GET to be sent to the editstudent.php script with the query parameter in the $_GET superglobal variable. We deal with this in the first if block:

1
2
if (isset($_GET['id_to_edit']))
{

They should be presented with a page like this:

In the form above, notice that the fields are pre-populated with the student details. We do this by querying the studentListing table for the student details before displaying the form.

Inside the if block, query the studentListing table for the student detials we want to edit using the id_to_edit query parameter by adding the following code:

editstudent.php - Edit Student: direct navigation to this Page from Student Details

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
if (isset($_GET['id_to_edit']))
{
    $id_to_edit = $_GET['id_to_edit'];

    $query = "SELECT * FROM studentListing WHERE id = $id_to_edit";

    $result = mysqli_query($dbc, $query)
        or trigger_error('Error querying database studentListing',
        E_USER_ERROR);

    if (mysqli_num_rows($result) == 1)
    {
        $row = mysqli_fetch_assoc($result);

        $student_first_name = $row['first_name'];
        $student_last_name = $row['last_name'];
        $student_email = $row['email'];
    }             
}

Display the Edit Form with Sticky Fields

Before working on the other conditions, let's add the form to update the student below all the conditional logic:

editstudent.php - Edit Student: Form for Updateing Student Details

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
    else // Unintended page link -  No student to edit, link back to index
    {
        header("Location: index.php");
    }         
?>
<form class="needs-validation" novalidate method="POST" 
      action="<?= $_SERVER['PHP_SELF'] ?>">
  <div class="form-group row">
    <label for="student_first_name"
            class="col-sm-3 col-form-label-lg">First Name</label>
    <div class="col-sm-8">
      <input type="text" class="form-control" id="student_first_name" 
              name="student_first_name" value= '<?=$student_first_name?>'
              placeholder="First Name" required>
      <div class="invalid-feedback">
        Please provide a valid first name.
      </div>
    </div>
  </div>
  <div class="form-group row">
    <label for="student_last_name" 
            class="col-sm-3 col-form-label-lg">Last Name</label>
    <div class="col-sm-8">
      <input type="text" class="form-control" id="student_last_name" 
              name="student_last_name" value= '<?=$student_last_name?>'
              placeholder="Last Name" required>
      <div class="invalid-feedback">
        Please provide a valid last name.
      </div>
    </div>
  </div>
  <div class="form-group row">
    <label for="student_email" 
            class="col-sm-3 col-form-label-lg">Email</label>
    <div class="col-sm-8">
      <input type="email" class="form-control" 
              id="student_email" 
              name="student_email"
              value= '<?=$student_email?>'
              placeholder="Email" required>
      <div class="invalid-feedback">
        Please provide a valid email address.
      </div>
    </div>
  </div>
  <button class="btn btn-primary" type="submit" 
          name="edit_student_submission">Update Student</button>
  <input type="hidden" name="id_to_update" value="<?= $id_to_edit ?>">
</form>

Notice above that the fields have been made "sticky".

Also notice above the hidden <input> element witht the name attribute set to id_to_update so we know which ID to update in the database.

Finally, also notice we are using Bootstrap's client side validation, so add the following JavaScript below the form:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
</form>
<script>
// JavaScript for disabling form submissions if there are invalid fields
(function() {
  'use strict';
  window.addEventListener('load', function() {
    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    var forms = document.getElementsByClassName('needs-validation');
    // Loop over them and prevent submission
    var validation = Array.prototype.filter.call(forms, function(form) {
      form.addEventListener('submit', function(event) {
        if (form.checkValidity() === false) {
          event.preventDefault();
          event.stopPropagation();
        }
        form.classList.add('was-validated');
      }, false);
    });
  }, false);
})();
</script>

This is the second intended way we will navigate to the editstudent.php page. Therefore we will be dealing with the elseif block:

1
2
3
4
elseif (isset($_POST['edit_student_submission'],
        $_POST['student_first_name'], $_POST['student_last_name'],
        $_POST['student_email'], $_POST['id_to_update']))
{

We're in this condition as a result of the user selecting the Update Student submit button.

Because the web is stateless, we needed to carry over the student id we received from the previous navigation to the editstudent.php script (which we received as a query parameter from the $_GET[] superglobal). We took that parameter and assigned it to a variable called $id_to_edit in the last HTTP transaction and assigning it to a hidden variable in the form which we can now access in the $_POST[] superglobal:

1
<input type="hidden" name="id_to_update" value="<?= $id_to_edit ?>">

Update the Student Details in the Database

In this elesif condition, we will update the student details in the studentListing table of the Student database. Add the following code within the elseif block:

editstudent.php - Edit Student: Navigation from Pressing the Update Student Button

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
elseif (isset($_POST['edit_student_submission'],
        $_POST['student_first_name'], $_POST['student_last_name'],
        $_POST['student_email'], $_POST['id_to_update']))
{
    $student_first_name = $_POST['student_first_name'];
    $student_last_name = $_POST['student_last_name'];
    $student_email = $_POST['student_email'];
    $id_to_update = $_POST['id_to_update'];

    $query = "UPDATE studentListing SET first_name = '$student_first_name', "
            . " last_name = '$student_last_name', email = '$student_email' "
            . "WHERE id = $id_to_update";

    mysqli_query($dbc, $query)
        or trigger_error(
            'Error querying database studentListing: Failed to update student listing',
            E_USER_ERROR);

    $nav_link = 'studentdetails.php?id=' . $id_to_update;

    header("Location: $nav_link");
}

Notice when we are done updating the database, we link back to the Student Details page.

Unanticipated Navigation Methods

As before, since the HTTP request is coming from the client. In theory, unanticipated or malicious parameters can be in the query string (or even field parameters from the HTTP POST). Therefore, all other conditions we could navigate to the editstudent.php page are unintended, and we will be dealing with the else block:

1
2
else // Unintended page link
{

In this case, we just want to link back to the main Student Listing main index.php page:

1
2
3
4
else // Unintended page link -  No student to edit, link back to index
{
    header("Location: index.php");
}         

Complete Code Listing

editstudent.php - Edit Student: Complete Code Listing

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<!DOCTYPE html>
<html>
  <head>
    <title>Edit Student</title>
    <link rel="stylesheet"
          href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css"
          integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS"
          crossorigin="anonymous">
  </head>
  <body>
    <div class="card">
      <div class="card-body">
        <h1>Edit a Student</h1>
        <nav class="nav">
          <a class="nav-link" href="index.php">Students</a>
        </nav>
        <hr/>
        <?php
            require_once('dbconnection.php');

            $dbc = mysqli_connect(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME)
                    or trigger_error('Error connecting to MySQL server for DB_NAME.',
                            E_USER_ERROR);

            if (isset($_GET['id_to_edit']))
            {
                $id_to_edit = $_GET['id_to_edit'];

                $query = "SELECT * FROM studentListing WHERE id = $id_to_edit";

                $result = mysqli_query($dbc, $query)
                    or trigger_error('Error querying database studentListing',
                    E_USER_ERROR);

                if (mysqli_num_rows($result) == 1)
                {
                    $row = mysqli_fetch_assoc($result);

                    $student_first_name = $row['first_name'];
                    $student_last_name = $row['last_name'];
                    $student_email = $row['email'];
                }             
            }
            elseif (isset($_POST['edit_student_submission'], $_POST['student_first_name'],
                            $_POST['student_last_name'], $_POST['student_email']))
            {
                $student_first_name = $_POST['student_first_name'];
                $student_last_name = $_POST['student_last_name'];
                $student_email = $_POST['student_email'];
                $id_to_update = $_POST['id_to_update'];

                $query = "UPDATE studentListing SET first_name = '$student_first_name', "
                        . " last_name = '$student_last_name', email = '$student_email' "
                        . "WHERE id = $id_to_update";

                mysqli_query($dbc, $query)
                    or trigger_error(
                        'Error querying database studentListing: Failed to update student listing',
                        E_USER_ERROR);

                $nav_link = 'studentdetails.php?id=' . $id_to_update;

                header("Location: $nav_link");          
            }
            else // Unintended page link
            {
                header("Location: index.php");
            }
        ?>
        <form class="needs-validation" novalidate method="POST" 
              action="<?= $_SERVER['PHP_SELF'] ?>">
          <div class="form-group row">
            <label for="student_first_name"
                    class="col-sm-3 col-form-label-lg">First Name</label>
            <div class="col-sm-8">
              <input type="text" class="form-control" id="student_first_name" 
                      name="student_first_name" value= '<?=$student_first_name?>'
                      placeholder="First Name" required>
              <div class="invalid-feedback">
                Please provide a valid first name.
              </div>
            </div>
          </div>
          <div class="form-group row">
            <label for="student_last_name" 
                    class="col-sm-3 col-form-label-lg">Last Name</label>
            <div class="col-sm-8">
              <input type="text" class="form-control" id="student_last_name" 
                      name="student_last_name" value= '<?=$student_last_name?>'
                      placeholder="Last Name" required>
              <div class="invalid-feedback">
                Please provide a valid last name.
              </div>
            </div>
          </div>
          <div class="form-group row">
            <label for="student_email" 
                    class="col-sm-3 col-form-label-lg">Email</label>
            <div class="col-sm-8">
              <input type="email" class="form-control" 
                      id="student_email" 
                      name="student_email"
                      value= '<?=$student_email?>'
                      placeholder="Email" required>
              <div class="invalid-feedback">
                Please provide a valid email address.
              </div>
            </div>
          </div>
          <button class="btn btn-primary" type="submit" 
                  name="edit_student_submission">Update Student</button>
          <input type="hidden" name="id_to_update" value="<?= $id_to_edit ?>">
        </form>
        <script>
        // JavaScript for disabling form submissions if there are invalid fields
        (function() {
          'use strict';
          window.addEventListener('load', function() {
            // Fetch all the forms we want to apply custom Bootstrap validation styles to
            var forms = document.getElementsByClassName('needs-validation');
            // Loop over them and prevent submission
            var validation = Array.prototype.filter.call(forms, function(form) {
              form.addEventListener('submit', function(event) {
                if (form.checkValidity() === false) {
                  event.preventDefault();
                  event.stopPropagation();
                }
                form.classList.add('was-validated');
              }, false);
            });
          }, false);
        })();
        </script>
      </div>
    </div>
    <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
            integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
            crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js"
            integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut"
            crossorigin="anonymous"></script>
    <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js"
            integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k"
            crossorigin="anonymous"></script>
  </body>
</html>