After my last code was vulnerable to sql injections, I tried to change it so much and make it as invulnerable as I understand it, but I'm not so sure I did a great job. So I made the following code for registering users and for logging them in, is this sql injection proof? I'm very scared about attacks.
<?php
session_start();
// initializing variables
$username = "";
$email = "";
$errors = array();
$check = isset($_POST['cbsu']) ? "checked" : "unchecked";
$db = mysqli_connect('', '', '', ''); //has real values in the actual file
if (isset($_POST['reg_user'])) {
$username = $_POST['username'];
$email = $_POST['email'];
$password_1 = $_POST['password_1'];
$password_2 = $_POST['password_2'];
if (empty($username)) { array_push($errors, "Username is required.");}
if (!preg_match("/^[a-zA-Z0-9]*$/", $username)){ array_push($errors, "Invalid username."); }
if (empty($email)) { array_push($errors, "Email is required");}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)){
array_push($errors, "Invalid email");
}
if (empty($password_1)) { array_push($errors, "Password is required"); }
if ($password_1 != $password_2) {
array_push($errors, "The two passwords do not match");
}
if($check == 'unchecked'){
array_push($errors, "You need to agree with the Terms and Conditions first.");
}
$sql = "SELECT * FROM users WHERE email = ? OR username = ?;";
$stmt = mysqli_stmt_init($db);
if (!mysqli_stmt_prepare($stmt, $sql)){
array_push($errors, "Something Went Wrong.");
}
else{
mysqli_stmt_bind_param($stmt, "ss", $email, $username);
mysqli_stmt_execute($stmt);
$resultData = mysqli_stmt_get_result($stmt);
if($roww = mysqli_fetch_assoc($resultData)){
if (strtolower($roww['username']) === strtolower($username)) {
array_push($errors, "Username already exists");
}
if ($roww['email'] === $email) {
array_push($errors, "Email already exists");
}
}
else{
$query = "INSERT INTO users (email, username, password) VALUES (?, ?, ?);";
$stmtt = mysqli_stmt_init($db);
if (!mysqli_stmt_prepare($stmtt, $query)){
array_push($errors, "Something Went Wrong.");
}
if (count($errors) == 0) {
$hashedpass = password_hash($password_1, PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmtt, "sss", $email, $username, $hashedpass);
mysqli_stmt_execute($stmtt);
mysqli_stmt_close($stmtt);
$_SESSION['username'] = strtoupper($username);
$_SESSION['success'] = "You are now logged in";
header('location: home.php');
}
}
}
mysqli_stmt_close($stmt);
}
// LOGIN USER
if (isset($_POST['login_user'])) {
$username = $_POST['username'];
$password = $_POST['password'];
if (empty($username)) {
array_push($errors, "Username is required");
}
if (empty($password)) {
array_push($errors, "Password is required");
}
$quer = "SELECT * FROM users WHERE username = ?;";
$stmttt = mysqli_stmt_init($db);
if (!mysqli_stmt_prepare($stmttt, $quer)){
array_push($errors, "Something Went Wrong.");
}
if (count($errors) == 0) {
mysqli_stmt_bind_param($stmttt, "s", $username);
mysqli_stmt_execute($stmttt);
$resultDataa = mysqli_stmt_get_result($stmttt);
if ($row = mysqli_fetch_assoc($resultDataa)) {
$checkpass = password_verify($password, $row["password"]);
if($checkpass === true){
$_SESSION['username'] = $row["username"];
$_SESSION['success'] = "You are now logged in";
header('location: home.php');
}
else{
array_push($errors, "Wrong password.");
}
}
else{
array_push($errors, "User not found");
}
mysqli_stmt_close($stmttt);
}
}
?>
If this is not invulnerable to injections, what changes should I make? Also, I would like to use mysqli instead of pdo, if possible.