The code below does exactly what it's expected to do. It adds a client into the database successfully. But I never told the query to execute or add a new client all I did was store the query in a variable and checked to see if it was valid in the if statement. I need some help understanding how the query executed.
$query = "INSERT INTO clients(id, name, email, phone, address, company, notes, date_added) VALUES(NULL, '$clientName', '$clientEmail', '$clientPhone', '$clientAddress', '$clientCompany', '$clientNotes', CURRENT_TIMESTAMP)";
$result = mysqli_query($connection, $query);
// if query was successful
if( $result ){
header("LOCATION: clients.php?update=success");
} else{
// something went wrong
echo "Error: $query <br>" . mysqli_error($connection);
}
The way you should be doing this is a little more self-explanatory:
// Prepare this query with placeholders for where the user data will go.
// This creates a prepared statement handle ($stmt)
$stmt = $connection->prepare("INSERT INTO clients(name, email, phone, address, company, notes, date_added)
VALUES(?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP)");
// Bind the user data to the statement so it will be escaped properly
// and inserted correctly.
$stmt->bind_param(
"ssssss",
$clientName,
$clientEmail,
$clientPhone,
$clientAddress,
$clientCompany,
$clientNotes
);
// Execute the statement now that everthing is in place. This actually
// sends the query to the MySQL server to be executed and waits
// for the result. The result of this function call indicates success
// or failure.
if ($stmt->execute()) {
// Query was successful then `execute()` returns a logically true value
// and this block of code will run.
header("Location: clients.php?update=success");
} else {
// If that previous condition didn't trigger, then we end up here and
// this code will run instead.
echo "Error: $query <br>" . $connection->error;
}
If you have an AUTO_INCREMENT
column don't specify it in your list of VALUES
, you can omit it and it will be populated automatically. Any column with a NULL
default can also be omitted. There's no point in force-inserting NULL
if that's how it will end up anyway.
You also need to pay careful attention to how you insert your data. You cannot use string interpolation to do this, it's extremely dangerous. The bind_param
method takes care of adding the data in a safe manner if you've created a prepared statement that has placeholder values (?
). This all but guarantees your code will be safe, secure and free from escaping errors that can take a lot of time to identify and repair.
I've also switched this to use the object-oriented style of mysqli
. Not only is this significantly less verbose, it also becomes more clear as to what the operation is being performed on. $stmt->function()
is obviously something making use of or manipulating the $stmt
object. If it's just one argument of many that can be harder to identify.
Specifying arguments directly to functions instead of leaning on these intermediate variables is also a good habit to get into. Things like $sql
tend to clutter up your code and confuse the intent of that string, plus if you have several of them you're juggling, like $sql3
and $sql8
there's an opportunity to make a tiny typo that causes real problems.