DELETE query

We know how to let users view records, change records, and create records. Just one operation left: delete.

Requirements

Let's start by working out what we want users to see. We made a view page like this:

View

Let's add a delete link:

Delete link

Here's the HTML to make the links:

  • print
  •     "<p class='operations-container'>
  •         <a href='add-edit-comedian-form.php?comedian_id={$comedianId}'>Edit</a>
  •         <a href='confirm-delete-comedian.php?comedian_id={$comedianId}'>Delete</a>
  •         <a href='add-edit-comedian-form.php'>Add new</a>
  •     </p>\n";

Let's think about this. When the user hits Delete, what should happen?

Reflect

When the user hits Delete, what should happen?

If you were logged in as a student, the lesson would pause here, and you'd be asked to type in a response. If you want to try that out, ask for an account on this site.
Adela
Adela

Don't just delete. Make sure the user didn't click it by accident.

Right! Something like this:

Confirm delete

If the user clicks delete:

Confirmed

This gives us a new principle:

Principle

Confirm destructive actions

People make mistakes. If there's a destructive action, like deleting a record, then confirm it with users.

One approach is the delete conformation page, as in the famous goats app. There's a delete link on each edit page.

Delete link

Click it, and the app asks you to confirm. It shows you the thing you would delete, too, so you can check it's the right one.

Confirm

It's easy to get into the habit of confirming everything, though. Another approach is to ask the user to type something about the thing to be deleted. That's what Github does. When you delete a repo, it asks you type the name of the repo as confirmation.

First step

Here's the delete link on the view page:

  • <a href='confirm-delete-comedian.php?comedian_id={$comedianId}'>Delete</a>

This link passes the comedian id. Here's confirm-delete-comedian.php:

  1. <?php
  2. // Connect to the database.
  3. require_once 'library/useful-stuff.php';
  4. $errorMessage = '';
  5. $comedianId = getParamFromGet('comedian_id');
  6. $errorMessage = checkComedianId($comedianId);
  7. if ($errorMessage == '') {
  8.     $comedianEntity = getComedianWithId($comedianId);
  9.     if (is_null($comedianEntity)) {
  10.         $errorMessage = "Sorry, there was a problem loading comedian with id $comedianId.";
  11.     }
  12.     else {
  13.         $comedianName = $comedianEntity['name'];
  14.         $comedianComments = $comedianEntity['comments'];
  15.     }
  16. }
  17. ?><!doctype html>
  18. <html lang="en">
  19.     <head>
  20.         <?php
  21.         $pageTitle = 'Confirm delete';
  22.         require_once 'library/page-components/head.php';
  23.         ?>
  24.     </head>
  25.     <body>
  26.         <div class="container">
  27.             <?php
  28.             require_once 'library/page-components/top.php'
  29.             ?>
  30.             <h1>Comedian</h1>
  31.             <?php
  32.             if ($errorMessage != '') {
  33.                 print "<p class='error-message'>$errorMessage</p>";
  34.             }
  35.             else {
  36.                 ?>
  37.                 <p>Are you sure you want to delete this comedian?</p>
  38.                 <p>Id: <?php print $comedianId; ?></p>
  39.                 <p>Name: <?php print $comedianName; ?></p>
  40.                 <p>Comments: <?php print $comedianComments; ?></p>
  41.                 <p class='operations-container'>
  42.                     <a href='delete-comedian.php?comedian_id=<?php print $comedianId; ?>'>Delete</a>
  43.                     <a href='view-comedian.php?comedian_id=<?php print $comedianId; ?>'>Forghedaboudit</a>
  44.                 </p>
  45.             <?php
  46.             }
  47.             require_once 'library/page-components/footer.php';
  48.             ?>
  49.     </body>
  50. </html>

It's mostly the same as the view page. The operation links are different:

  • <p class='operations-container'>
  •     <a href='delete-comedian.php?comedian_id=<?php print $comedianId; ?>'>Delete</a>
  •     <a href='view-comedian.php?comedian_id=<?php print $comedianId; ?>'>Forghedaboudit</a>
  • </p>

The first one goes through with the delete. The Forghedaboudit link jumps back to the view page.

Doing the delete

We could run the DELETE and jump to another page, but instead, we'll let the user know what happened.

After delete

Here's the PHP that deletes the record, and makes the display.

  1. <?php
  2. // Connect to the database.
  3. require_once 'library/useful-stuff.php';
  4. $errorMessage = '';
  5. $comedianId = getParamFromGet('comedian_id');
  6. $errorMessage = checkComedianId($comedianId);
  7. if ($errorMessage == '') {
  8.     $comedianEntity = getComedianWithId($comedianId);
  9.     if (is_null($comedianEntity)) {
  10.         $errorMessage = "Sorry, there was a problem loading comedian with id $comedianId.";
  11.     }
  12.     else {
  13.         // Put the field values into variables.
  14.         $comedianName = $comedianEntity['name'];
  15.         $comedianComments = $comedianEntity['comments'];
  16.         // Delete.
  17.         $sql = "DELETE FROM comedians WHERE comedian_id = :id;";
  18.         /** @var PDO $dbConnection */
  19.         $stmnt = $dbConnection->prepare($sql);
  20.         $stmnt->execute([':id' => $comedianId]);
  21.     }
  22. }
  23. ?><!doctype html>
  24. <html lang="en">
  25.     <head>
  26.         <?php
  27.         $pageTitle = 'Deleted';
  28.         require_once 'library/page-components/head.php';
  29.         ?>
  30.     </head>
  31.     <body>
  32.         <div class="container">
  33.             <?php
  34.             require_once 'library/page-components/top.php'
  35.             ?>
  36.             <h1>Comedian deleted</h1>
  37.             <?php
  38.             if ($errorMessage != '') {
  39.                 print "<p class='error-message'>$errorMessage</p>";
  40.             }
  41.             else {
  42.                 ?>
  43.                 <p>This comedian was deleted:</p>
  44.                 <p>Id: <?php print $comedianId; ?></p>
  45.                 <p>Name: <?php print $comedianName; ?></p>
  46.                 <p>Comments: <?php print $comedianComments; ?></p>
  47.                 <?php
  48.             }
  49.             require_once 'library/page-components/footer.php';
  50.             ?>
  51.     </body>
  52. </html>

The only new thing is the SQL DELETE statement.

  • $sql = "DELETE FROM comedians WHERE comedian_id = :id;";
  • $stmnt = $dbConnection->prepare($sql);
  • $stmnt->execute([':id' => $comedianId]);

The WHERE clause identifies the record to delete.

Up next

Let's make a report listing the comedians, with an operation link for each.