Jump to content

PHP Create Not Inserting Into Db And Check If Exists


exceedinglife

Recommended Posts

Hello all, I have another project I’m working on a php login and I am inserting a record in the db I’m checking the table to see if it exists or not so there can’t be 2 users with the same username but I am working with create the form submits but nothing is inserted. Also appreciate suggestions in code to make my php better.

<?php
    //mySQL database config
require_once "config.php";

// Define all variables and initialize them as 'empty'
$name = $username = $password = $password2 = "";
$nameerror = $usernameerror = $passworderror = $password2error = "";

// Process data when the form is submitted.
if($_SERVER["REQUEST_METHOD"] == "POST") {

    //Name check
    if(empty(trim($_POST["name"]))) {
        $nameerror = "Please enter a name.";
    } else {
        $name = trim($_POST["name"]);
    }
    // Validate 'Username'
    if(empty(trim($_POST["username"]))) {
        $usernameerror = "Please enter a Username.";
    } else {
        // Prepare a SELECT statement.
        $sql = "SELECT userid FROM users WHERE username = :username";

        if($stmt = $pdoConn->prepare($sql)) {
            // Bind variables to prepared statement as parameters
            $stmt->bindParam(":username", $param_username, PDO::PARAM_STR);
            // Set parameters
            $param_username = trim($_POST["username"]);
            // Attempt to execute prepared statement
            if($stmt->execute()) {
                if($stmt->rowCount() == 1) {
                    $usernameerror = "Username is already taken.";
                } else {
                    $username = trim($_POST["username"]);
                }
            } else {
                echo "Something went wrong with SELECT, please try again later.";
            }
        }
        // Close $stmt
        unset($stmt);
    }
    // Validate Password
    if(empty(trim($_POST["password"]))) {
        $passworderror = "Please enter a password.";
    } else if (strlen(trim($_POST["password"])) < 6) {
        $passworderror = "Password must have at least 6 characters.";
    } else {
        $password = trim($_POST["password"]);
    }
    // Validate Confirm Password.
    if(empty(trim($_POST["password2"]))) {
        $password2error = "Please confirm your password";
    } else {
        $pass2 = trim($_POST["password2"]);
        if(empty($password2error) && ($password != $pass2)) {
            $password2error = "Passwords <b>DID NOT</b> match.";
        }
    }
    //Check for inputs on form to continue.
    // Error checks or input checks.
    if(empty($name) && empty($username) && empty($password) && empty($password2)) {
        // Prepare SELECT statement
        $sql = "INSERT INTO  users (name, username, password) " .
               "VALUES (:name, :username, :password)";
        if($stmt = $pdoConn->prepare($sql)) {
            // Bind variables to prepared statement as parameters
            $stmt->bindParam(":name", $param_name, PDO::PARAM_STR);
            $stmt->bindParam(":username", $param_username, PDO::PARAM_STR);
            $stmt->bindParam(":password", $param_pass, PDO::PARAM_STR);
            // Set parameters
            $para_name = $name;
            $param_username = $username;
            $param_pass = password_hash($password, PASSWORD_DEFAULT);
            // attempt to execute the prepared Statement
            if($stmt->execute()){
                header("Location: ../index.php");
            } else {
                echo "Something went wrong with INSERT";
            }

        }
        // Close Statement
        unset($stmt);
    }
    // Close connection
    unset($pdoConn);
}


?>

 

Link to comment
Share on other sites

to do what you are asking, just make the username column a unique index, forget about the SELECT query, just run the INSERT query, and test if there was a duplicate key error. if there is, it means that the username already exists. this alone will eliminate a 1/4th of the code.

in addition to the suggestions already given in a previous thread, this code is filled with unnecessary and repetitive logic, mistyped and non-existent variable names (which is why some of the code isn't running.) you even have a backward logic test that would only run the INSERT query if all the variables are empty. you need to use the simplest and most general purpose code that accomplishes a task. what you are doing now is creating a wall of code which is hiding the mistakes. you have a 'cannot see the forest for the trees' problem.

some more suggestions -

1) forget about making discrete variables for every form field and every error. use arrays instead. one for the trimmed input data and one for the errors.

2) trim all the input values at one time. if i/someone has time they will post an example that takes only one line of code.

3) when you validate the inputs, store any error messages in an array. this array is also an error flag. if the array is empty, there are no validation errors. if the array is not empty, there are errors. after all the validation tests, if the array is empty, you can use the submitted data. in your html document, if the array is not empty, display the errors by displaying the contents of the error array.

4) stop creating variables for nothing. in this thread and your other current thread, you have variables that don't exist and typo mistakes in variable names. by using an array to hold a trimmed copy of the input data, then using just this array in the rest of the code, hopefully it will cut down on these type of mistakes. 

Link to comment
Share on other sites

here's code (partially tested only) that uses the suggestions above and from the previous thread -

<?php
//mySQL database config
require "config.php";

// Define all variables and initialize them as 'empty'
$errors = []; // an array to hold error messages and serves as an error flag
$post = []; // an array to hold the trimmed input data

// Process data when the form is submitted.
if($_SERVER["REQUEST_METHOD"] == "POST")
{
	// assuming the $_POST field names in the original code are accurate, the inputs to this code are -
	// name, username, password, and password2

	$post = array_map('trim',$_POST); // get a trimmed copy of the $_POST data (if any of the form fields are arrays, you need a recursive trim call-back function in this line instead of php's trim() function)

	//Name check
	if(empty($post["name"]))
	{
		$errors['name'] = "Please enter a name.";
	}

	// Validate 'Username'
	if(empty($post["username"]))
	{
		$errors['username'] = "Please enter a Username.";
	}
	
	// Validate Password
	if(empty($post["password"]))
	{
		$errors['password'] = "Please enter a password.";
	} else {
		if(strlen($post["password"]) < 6)
		{
			$errors['password'] = "Password must have at least 6 characters.";
		}
	}

	// Validate Confirm Password.
	if(empty($post["password2"]))
	{
		$errors['password2'] = "Please confirm your password";
	}

	// check password and confirm password
	if(empty($errors['password']) && empty($errors['password2']) && $post['password'] != $post['password2'])
	{
		$errors['password_confirm'] = "Password and confirmed password do not match.";
	}

	// if no validation errors, use the submitted data
	if(empty($errors))
	{
		$sql = "INSERT INTO users (name, username, password)
				VALUES (:name, :username, :password)";
		$stmt = $pdoConn->prepare($sql);
		
		// use a 'local' try/catch to handle errors from this query
		try {
			$stmt->execute([
				":name"=>$post['name'],
				":username"=>$post['username'],
				":password"=>password_hash($post['password'], PASSWORD_DEFAULT)
			]);
		} catch (PDOException $e) {
			$er=$e->errorInfo(); // get the error information 
			if($er[1] == 1062){ // duplicate key error number
				$errors['username'] = "The username is already in use.";
			} else {
				throw $e; // re-throw the pdoexception if the error is not handled by this logic
			}
		}
		
		// if no errors, the insert was successful
		if(empty($errors))
		{
			header("Location: ../index.php");
			exit;
		}
	}
}

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.