Ferrius Ferrius - 2 months ago 10
MySQL Question

What does this mean? and how do I solve it? Uncaught exception 'PDOException' with message 'SQLSTATE[42000]

I've been building a signup form, using PDO. I'm new to PDO so I don't fully understand why I get that error. I checked my code, and it doesn't seem to be any syntax mistake. I don't know what it means when it says access violation.

I keep getting this error:


Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]


This is my connect file

<?php

//Our MySQL user account.
define('MYSQL_USER', 'root');

//Our MySQL password.
define('MYSQL_PASSWORD', '');

//The server that MySQL is located on.
define('MYSQL_HOST', 'localhost');

//The name of our database.
define('MYSQL_DATABASE', 'private_beta_squire_app');

/**
* PDO options / configuration details.
* I'm going to set the error mode to "Exceptions".
* I'm also going to turn off emulated prepared statements.
*/
$pdoOptions = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false
);

/**
* Connect to MySQL and instantiate the PDO object.
*/
$pdo = new PDO(
"mysql:host=" . MYSQL_HOST . ";dbname=" . MYSQL_DATABASE, //DSN
MYSQL_USER, //Username
MYSQL_PASSWORD, //Password
$pdoOptions //Options
);

?>


And this is my form code

<?php

require 'password.php';

if ( isset ( $_POST ['submitButton'] ) ) {

//if ( empty ( $_POST ['mail'] ) ) {
//echo "Type your mail";
//}

//if ( empty ( $_POST ['password'] ) ) {
//echo "Type your password";
//}

//if ( empty ( $_POST ['name'] ) ) {
//echo "Type your name";
//}

//else {

//Retrieve the field values from our registration form.
$username = !empty ( $_POST ['mail'] ) ? trim ( $_POST ['mail'] ) : null;
$pass = !empty ( $_POST ['password'] ) ? trim ( $_POST ['password'] ) : null;
$name = !empty ( $_POST ['name'] ) ? trim ( $_POST ['name'] ) : null;
$status = 'off';

//TO ADD: Error checking (username characters, password length, etc).
//Basically, you will need to add your own error checking BEFORE
//the prepared statement is built and executed.

//Now, we need to check if the supplied username already exists.

//Construct the SQL statement and prepare it.
$sql = "SELECT COUNT( email ) AS num FROM users WHERE email = :username";
$stmt = $pdo->prepare ( $sql );

//Bind the provided username to our prepared statement.
$stmt->bindValue ( ':username', $username );

//Execute.
$stmt->execute();

//Fetch the row.
$row = $stmt->fetch ( PDO::FETCH_ASSOC) ;

//If the provided username already exists - display error.
//TO ADD - Your own method of handling this error. For example purposes,
//I'm just going to kill the script completely, as error handling is outside
//the scope of this tutorial.
if ( $row ['num'] > 0 ) {

die ( 'That email is already registered!' );

}

//Hash the password as we do NOT want to store our passwords in plain text.
$passwordHash = password_hash ( $pass, PASSWORD_BCRYPT, array ( "cost" => 12 ) );

//Prepare our INSERT statement.
//Remember: We are inserting a new row into our users table.
$sql = "INSERT INTO users (email, name, status, pass) VALUES (:username, :name, :status, :password;)";
$stmt = $pdo->prepare($sql);

//Bind our variables.
$stmt->bindValue (':username', $username);
$stmt->bindValue (':name', $name);
$stmt->bindValue (':name', $status);
$stmt->bindValue (':password', $passwordHash);

//Execute the statement and insert the new account.
$result = $stmt->execute();

//If the signup process is successful.
if ( $result ) {

//What you do here is up to you!
header('location: index.php');

}
//}
}

?>

Answer

You have two issues.

$sql = "INSERT INTO users (email, name, status, pass) VALUES (:username, :name, :status, :password;)";
  1. The `;` after the `password` placeholder closes the `insert` statement, which makes the query invalid.
$stmt->bindValue (':name', $name);
$stmt->bindValue (':name', $status);
  1. Here you have used the same placeholder name twice, although your query used the correct name. If you used non-named placeholders this wouldn't have caused an issue.

So you should have:

$sql = "INSERT INTO users (email, name, status, pass) VALUES (:username, :name, :status, :password)";
        $stmt = $pdo->prepare($sql);

        //Bind our variables.
        $stmt->bindValue (':username', $username);
        $stmt->bindValue (':name', $name);
        $stmt->bindValue (':status', $status);
        $stmt->bindValue (':password', $passwordHash);      

        //Execute the statement and insert the new account.
        $result = $stmt->execute();

Alternative:

$sql = "INSERT INTO users (email, name, status, pass) VALUES (?, ?, ?, ?)";
        $stmt = $pdo->prepare($sql);
        //Bind and execute the statement and insert the new account.
        $result = $stmt->execute(array($username, $name, $status, $passwordHash));