Solution 1 :

Code that fixed my problem was this one

<?php
if (isset($_POST['submit'])) {
    $order = $_POST['orderId'];

    if ($order != "") {
        try {

        $db = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8', 'username', 'password');

        $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
        $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $order = $_POST['orderId'];

        $stmt = $db->prepare("SELECT * FROM Orders where OrderId = :orderid ");
        $stmt->execute([ ':orderid' => $order ]);
        if ($stmt->fetch(PDO::FETCH_ASSOC)) {
            $subject = $_POST['subject'];
            $message = $_POST['message'];
            $order = $_POST['orderId'];
            $mailTo = "[email protected]";
            $txt .= "Query Received!nnOrder ID: ".$order."nnMessage context: nn".$message;
            mail($mailTo, $subject, $txt);
        }
        else {
            echo "No such ID.";
        }

        }
        catch (PDOException $e) {
            print "Error!: " . $e->getMessage() . "<br/>";
            die();
        }
    }
    else {
        $subject = $_POST['subject'];
        $message = $_POST['message'];
        $order = $_POST['orderId'];
        $mailTo = "[email protected]";
        $txt .= "Report received!nn"."Message context: nn".$message;
        mail($mailTo, $subject, $txt);
    }
}
?>

Making code to work


Problem with original code was part if (!$row = $stmt->fetch(PDO::FETCH_ASSOC)). It didn’t do the job.

That’s why, after executing $stmt->execute([ ':orderid' => $order ]);, needed to fetch data searched in table and then if there is such row fetched, send an email. If there is no such row, give an error “No such ID.”

if ($stmt->fetch(PDO::FETCH_ASSOC)) {
  $subject = $_POST['subject'];
  $message = $_POST['message'];
  $order = $_POST['orderId'];
  $mailTo = "[email protected]";
  $txt .= "Query Received!nnOrder ID: ".$order."nnMessage context: nn".$message;
  mail($mailTo, $subject, $txt);
}
else {
  echo "No such ID.";
}

Also, I have moved part of code that sends email to run separately with all it’s variables after doing all the job with searching:

  1. If orderId input is empty or not: if ($order != "")
  2. If orderId input is empty, check if there is actual row in table specified in OrderId input

At the end, used catch, which in coding progress itself helps you to check if code in try works

Read more about prepared statements: https://www.php.net/manual/en/pdo.prepared-statements.php

Read more about PDO connections and connection managing: https://www.php.net/manual/en/pdo.connections.php

Preventing SQL injection


Article How can I prevent SQL injection in PHP?

Using setAttribute() when connecting to database:

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

What is mandatory, however, is the first setAttribute() line, which tells PDO to disable emulated prepared statements and use real prepared statements. This makes sure the statement and the values aren’t parsed by PHP before sending it to the MySQL server (giving a possible attacker no chance to inject malicious SQL).

Second, using prepared statements when searching for specified row:

$order = $_POST['orderId'];

$stmt = $db->prepare("SELECT * FROM Orders where OrderId = :orderid ");
$stmt->execute([ ':orderid' => $order ]);

Problem :

I have email contact in PHP and I wanted to add part where it should check if there is actual order ID written in <input> in my table, otherwise, it sends email.

EDIT: added prepared statement $stmt->execute([ ':order' => $order ]);

<?php
if (isset($_POST['submit'])) {
$subject = $_POST['subject'];
$message = $_POST['message'];
$order = $_POST['orderId'];
$mailTo = "[email protected]";
        if ($order != "") {
          $db = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8', 'username', 'password');
          $order = $_POST['orderId'];

          $stmt = $db->query("SELECT * FROM Orders WHERE OrderID= :order ");
          $stmt->execute([ ':order' => $order ]);

          if (!$row = $stmt->fetch(PDO::FETCH_ASSOC)) {
              echo 'No such ID';
          }
          else {
              $txt .= "Query Received!nnOrder ID: ".$order."nnMessage context: nn".$message;
              mail($mailTo, $subject, $txt);
          }
        }
        else {
                $txt .= "Bug report received!nn"."Message context: nn".$message;
                mail($mailTo, $subject, $txt);
        }
}
?>

And my HTML:

        <center><form class="query-form" method="post">
 <input style="width: 300px;" class="orderId" type="text" name="orderId" placeholder="Order ID.     Leave blank if reporting a bug">
 <br>
 <input required style="width: 300px;" type="text" name="subject" placeholder="Subject">
 <br>
 <textarea required name="message" placeholder="Query text" style="width: 300px;" maxlength = "700"></textarea>
 <br>
 <input type="submit" name="submit" placeholder="Send Query">
</form></center>

When I fill up orderId input and on purpose type characters that aren’t in my table (“test”), it still sends an email ( while it should echo that there is no such order ID provided in input):

Query Received!

Order ID:

Message context:

Test

But when I leave orderId empty, PHP works just fine and gives me second message, as wanted.

Can you please tell me why it’s just going through that code?

Comments

Comment posted by miken32

According to the documentation for

Comment posted by prepared statements

WARNING

Comment posted by tadman

There’s nothing much to “get”, you just put things like

Comment posted by tadman

The

Comment posted by tadman

It’s not the email part, it’s the injection into SQL part that’s the huge issue. Within the context of

By