Let's say you have this code (Just an example to give idea)
Method 1 (NEVER RECOMMENDED)
<?php
$username=$_POST['user'];
$password=$_POST['pass'];
$sql = "SELECT * FROM users WHERE username LIKE '".$_POST['user']."'";
//Execute the query
?>
<form action='' method='post'>
<input name=user>
<input name=pass>
<input type='submit'>
</form>
Now this is vulnerable to SQL injection. If a user inputs
abc'; DROP TABLE users;
This query will be rendered as
"SELECT * FROM users WHERE username LIKE 'abc'; DROP TABLE users";
Now there are two queries first it performs SELECT then it performs DROP
hence at the end your users
table is dropped.
Method 2 (Prepared Statements RECOMMENDED)
<?php
$username=$_POST['user'];
$password=$_POST['pass'];
$stmt = $mysqli->prepare("SELECT * FROM users WHERE username LIKE ?");
$stmt->bind_param("s", $_POST['user']);
$stmt->execute();
//Execute the query
?>
<form action='' method='post'>
<input name=user>
<input name=pass>
<input type='submit'>
</form>
Now at line $stmt->$mysqli->prepare()
in simple words, it will go to MySQL and tell that there is a query coming with a parameter.
Then bind_param
will go and registers itself to MySQL as a parameter only. And thus executes.
I cannot write in more simpler words. Hope you get the idea!