1

Upon registering for an account for a subscription based product, I would like users to take a quiz. I want the results to be stored in a MySQL database. I've been using PHP and MySQL.

I have been able to have the quiz results and membership signup information sent to the database successfully, but verifying it is my issue because when the user goes back one page, then the quiz is reset.

For example, if a username is taken, the user is given an error and sent back to the quiz having to re-do the whole thing.

If there is a simple way to do it, I am interested in having javascript search the MySQL database for conditions such as if a username/email is already in use.

Right now, I have a javascript function that is called upon submitting the form. It currently only verifies that the two typed in passwords match each other. I would also it to call another function that searches that database and returns false if the username/email exists so that the user is not taken into another page.

This is how the code looks so far.

I am only experienced with very basic uses of php/MySQL. So my way of figuring this out was taking a free php/MySQL user system and modifying it to also insert results of the quiz into the table.

This is a common.php file that I include on each page. '

// These variables define the connection information for your MySQL database 
$username = "root"; 
$password = "*******"; 
$host = "localhost"; 
$dbname = "cc4u2"; 

// UTF-8 is a character encoding scheme that allows you to conveniently store 
// a wide varienty of special characters, like ¢ or €, in your database. 
// By passing the following $options array to the database connection code we 
// are telling the MySQL server that we want to communicate with it using UTF-8
// See Wikipedia for more information on UTF-8: 
// http://en.wikipedia.org/wiki/UTF-8 
$options = array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'); 

// A try/catch statement is a common method of error handling in object oriented code. 
// First, PHP executes the code within the try block.  If at any time it encounters an 
// error while executing that code, it stops immediately and jumps down to the 
// catch block.  For more detailed information on exceptions and try/catch blocks: 
// http://us2.php.net/manual/en/language.exceptions.php 
try 
{ 
    // This statement opens a connection to your database using the PDO library
    // PDO is designed to provide a flexible interface between PHP and many 
    // different types of database servers.  For more information on PDO: 
    // http://us2.php.net/manual/en/class.pdo.php 
    $db = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options); 
} 
catch(PDOException $ex) 
{ 
    // If an error occurs while opening a connection to your database, it will 
    // be trapped here.  The script will output an error and stop executing. 
    // Note: On a production website, you should not output $ex->getMessage(). 
    // It may provide an attacker with helpful information about your code 
    // (like your database username and password). 
    die("Failed to connect to the database: " . $ex->getMessage()); 
} 

// This statement configures PDO to throw an exception when it encounters 
// an error.  This allows us to use try/catch blocks to trap database errors. 
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

// This statement configures PDO to return database rows from your database using an associative 
// array.  This means the array will have string indexes, where the string value 
// represents the name of the column in your database. 
$db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); 

// This block of code is used to undo magic quotes.  Magic quotes are a terrible 
// feature that was removed from PHP as of PHP 5.4.  However, older installations 
// of PHP may still have magic quotes enabled and this code is necessary to 
// prevent them from causing problems.  For more information on magic quotes: 
// http://php.net/manual/en/security.magicquotes.php 
if(function_exists('get_magic_quotes_gpc') && get_magic_quotes_gpc()) 
{ 
    function undo_magic_quotes_gpc(&$array) 
    { 
        foreach($array as &$value) 
        { 
            if(is_array($value)) 
            { 
                undo_magic_quotes_gpc($value); 
            } 
            else 
            { 
                $value = stripslashes($value); 
            } 
        } 
    } 

    undo_magic_quotes_gpc($_POST); 
    undo_magic_quotes_gpc($_GET); 
    undo_magic_quotes_gpc($_COOKIE); 
} 

// This tells the web browser that your content is encoded using UTF-8 
// and that it should submit content back to you using UTF-8 
header('Content-Type: text/html; charset=utf-8'); 

// This initializes a session.  Sessions are used to store information about 
// a visitor from one web page visit to the next.  Unlike a cookie, the information is 
// stored on the server-side and cannot be modified by the visitor.  However, 
// note that in most cases sessions do still use cookies and require the visitor 
// to have cookies enabled.  For more information about sessions: 
// http://us.php.net/manual/en/book.session.php 
session_start(); 

// Note that it is a good practice to NOT end your PHP files with a closing PHP tag. 
// This prevents trailing newlines on the file from being included in your output, 
// which can cause problems with redirecting users.

This is at the top of registration.php

// First we execute our common code to connection to the database and start the session 
require("common.php"); 

// This if statement checks to determine whether the registration form has been submitted 
// If it has, then the registration code is run, otherwise the form is displayed 
if(!empty($_POST)) 
{ 
    // Ensure that the user has entered a non-empty username 
    if(empty($_POST['username'])) 
    { 
        // Note that die() is generally a terrible way of handling user errors 
        // like this.  It is much better to display the error with the form 
        // and allow the user to correct their mistake.  However, that is an 
        // exercise for you to implement yourself. 
        die("Please enter a username."); 
    } 

    // Ensure that the user has entered a non-empty password 
    if(empty($_POST['password'])) 
    { 
        die("Please enter a password."); 
    } 

    // Make sure the user entered a valid E-Mail address 
    // filter_var is a useful PHP function for validating form input, see: 
    // http://us.php.net/manual/en/function.filter-var.php 
    // http://us.php.net/manual/en/filter.filters.php 
    if(!filter_var($_POST['email'], FILTER_VALIDATE_EMAIL)) 
    { 
        die("Invalid E-Mail Address"); 
    } 

    // We will use this SQL query to see whether the username entered by the 
    // user is already in use.  A SELECT query is used to retrieve data from the database. 
    // :username is a special token, we will substitute a real value in its place when 
    // we execute the query. 
    $query = " 
        SELECT 
            1 
        FROM users 
        WHERE 
            username = :username 
    "; 

    // This contains the definitions for any special tokens that we place in 
    // our SQL query.  In this case, we are defining a value for the token 
    // :username.  It is possible to insert $_POST['username'] directly into 
    // your $query string; however doing so is very insecure and opens your 
    // code up to SQL injection exploits.  Using tokens prevents this. 
    // For more information on SQL injections, see Wikipedia: 
    // http://en.wikipedia.org/wiki/SQL_Injection 
    $query_params = array( 
        ':username' => $_POST['username'] 
    ); 

    try 
    { 
        // These two statements run the query against your database table. 
        $stmt = $db->prepare($query); 
        $result = $stmt->execute($query_params); 
    } 
    catch(PDOException $ex) 
    { 
        // Note: On a production website, you should not output $ex->getMessage(). 
        // It may provide an attacker with helpful information about your code.  
        die("Failed to run query: " . $ex->getMessage()); 
    } 

    // The fetch() method returns an array representing the "next" row from 
    // the selected results, or false if there are no more rows to fetch. 
    $row = $stmt->fetch(); 

    // If a row was returned, then we know a matching username was found in 
    // the database already and we should not allow the user to continue. 
    if($row) 
    { 
        die("This username is already in use"); 
    } 

    // Now we perform the same type of check for the email address, in order 
    // to ensure that it is unique. 
    $query = " 
        SELECT 
            1 
        FROM users 
        WHERE 
            email = :email 
    "; 

    $query_params = array( 
        ':email' => $_POST['email'] 
    ); 

    try 
    { 
        $stmt = $db->prepare($query); 
        $result = $stmt->execute($query_params); 
    } 
    catch(PDOException $ex) 
    { 
        die("Failed to run query: " . $ex->getMessage()); 
    } 

    $row = $stmt->fetch(); 

    if($row) 
    { 
        die("This email address is already registered"); 
    } 



    // An INSERT query is used to add new rows to a database table. 
    // Again, we are using special tokens (technically called parameters) to 
    // protect against SQL injection attacks. 
    $query = " 
        INSERT INTO users ( 
            username, 
            password, 
            salt, 
            email,
            style
        ) VALUES ( 
            :username, 
            :password, 
            :salt, 
            :email,
            :style
        ) 
    "; 

    // A salt is randomly generated here to protect again brute force attacks 
    // and rainbow table attacks.  The following statement generates a hex 
    // representation of an 8 byte salt.  Representing this in hex provides 
    // no additional security, but makes it easier for humans to read. 
    // For more information: 
    // http://en.wikipedia.org/wiki/Salt_%28cryptography%29 
    // http://en.wikipedia.org/wiki/Brute-force_attack 
    // http://en.wikipedia.org/wiki/Rainbow_table 
    $salt = dechex(mt_rand(0, 2147483647)) . dechex(mt_rand(0, 2147483647)); 

    // This hashes the password with the salt so that it can be stored securely
    // in your database.  The output of this next statement is a 64 byte hex 
    // string representing the 32 byte sha256 hash of the password.  The original 
    // password cannot be recovered from the hash.  For more information: 
    // http://en.wikipedia.org/wiki/Cryptographic_hash_function 
    $password = hash('sha256', $_POST['password'] . $salt); 

    // Next we hash the hash value 65536 more times.  The purpose of this is to
    // protect against brute force attacks.  Now an attacker must compute the hash 65537 
    // times for each guess they make against a password, whereas if the password 
    // were hashed only once the attacker would have been able to make 65537 different  
    // guesses in the same amount of time instead of only one. 
    for($round = 0; $round < 65536; $round++) 
    { 
        $password = hash('sha256', $password . $salt); 
    } 

    // Here we prepare our tokens for insertion into the SQL query.  We do not 
    // store the original password; only the hashed version of it.  We do store
    // the salt (in its plaintext form; this is not a security risk). 
    $query_params = array( 
        ':username' => $_POST['username'], 
        ':password' => $password, 
        ':salt' => $salt, 
        ':email' => $_POST['email'],
        ':style' => $_POST['style'] 
    ); 

    try 
    { 
        // Execute the query to create the user 
        $stmt = $db->prepare($query); 
        $result = $stmt->execute($query_params); 
    } 
    catch(PDOException $ex) 
    { 
        // Note: On a production website, you should not output $ex->getMessage(). 
        // It may provide an attacker with helpful information about your code.  
        die("Failed to run query: " . $ex->getMessage()); 
    } 

    // This redirects the user back to the login page after they register 
    header("Location: login.php"); 

    // Calling die or exit after performing a redirect using the header function 
    // is critical.  The rest of your PHP script will continue to execute and 
    // will be sent to the user if you do not die or exit. 
    die("Redirecting to login.php"); 
} 
 ?> 

This is the javascript code that checks that the two entered passwords match

function checkPassword() {
    var pass1 = document.getElementById("pass").value;
    var pass2 = document.getElementById("c_pass").value;

    if (pass1 != pass2) {   
        alert("Your passwords do not match.");
        return false;
    }

    document.getElementById("quizForm").method="post";
    document.getElementById("quizForm").action="register.php";
}

And of course here is a bit of the html of the quiz. I just included one question for the sake of length since this is already a long post. This is located in registration.php below the php code.

<form id="quizForm"> 
<h2>Which Style?</h2>
Classy <input type="radio" name="style" value="Classy"><br>
Formal <input type="radio" name="style" value="Formal"><br>
Alternative <input type="radio" name="style" value="Alternative"><br>
Natural <input type="radio" name="style" value="Natural"><br>
Night Life <input type="radio" name="style" value="Nightlife"><br>
Businessman/Professional <input type="radio" name="style" value="Businessman/Professional"><br>
Hip/Vintage <input type="radio" name="style" value="Hip/Vintage"><br>
Seductive <input type="radio" name="style" value="Seductive"><br>
Athletic <input type="radio" name="style" value="Athletic"><br>
Worldly <input type="radio" name="style" value="Worldly"><br>
<br>
    Username:<br /> 
<input type="text" name="username">
<br /><br /> 
E-Mail:<br /> 
<input type="text" name="email" value="emaiil" placeholder="Email" />
<br /><br /> 
Password:<br />
<input type="password" id="pass" name="password">
<br /><br /> 
Confirm Password:<br>
<input type="password" id="c_pass" name="password">
<input type="submit" onclick="return checkPassword();" value="Register" name="Submit">
</form>
Mark
  • 2,380
  • 11
  • 29
  • 49
AndrewMRiv
  • 155
  • 2
  • 11
  • 4
    The keyword you are looking for is `AJAX`, and the examples are numerous. :) – GolezTrol May 14 '14 at 17:52
  • 1
    What @GolezTrol said is true, search for ajax. Besides, try to post localized problems in your questions, not so generic with huge code snippets, this makes things hard you and us. – DontVoteMeDown May 14 '14 at 17:53
  • Not nearly as many comments as you have but here's an AJAX example =) http://stackoverflow.com/questions/20150130/ajax-and-php-to-enter-multiple-forms-input-to-database/20150474#20150474 – MonkeyZeus May 14 '14 at 18:03
  • I am not so sure trying to redo this in Javascript will be the best thing considering your level. It looks like it may be helpful just to refill the form inputs on an error. – Brian May 14 '14 at 18:39
  • Here's a way you can simply refill the form inputs on error. You will need to refactor your code so that it is not using `die` to log the errors. Here is an example using try/catch: https://gist.github.com/anoxic/11dd6cacfbeafbaac330 – Brian May 14 '14 at 18:54

1 Answers1

0

JavaScript runs on clients computer, it cannot do anything like this.

But, there is an option that you send an ajax request to a php file which would verify the data and then echo the result back to browser.

For more about AJAX: http://www.w3schools.com/php/php_ajax_php.asp

prakhar19
  • 465
  • 4
  • 18