Jump to content

PHP Registration Form Displaying Error


bob123

Recommended Posts

I've got quite a large.. and secure PHP registration form, however when I fill it in, I'm being provided with the error Registration Failed, which is only meant to display if there's an error signing up, and I can't work out what the error is..

 

MYSQL Code

CREATE TABLE IF NOT EXISTS `users` (
`username` varchar(30) NOT NULL,
`password` varchar(32) DEFAULT NULL,
`userid` varchar(32) DEFAULT NULL,
`userlevel` tinyint(1) unsigned NOT NULL,
`email` varchar(50) DEFAULT NULL,
`timestamp` int(11) unsigned NOT NULL,
`valid` tinyint(1) unsigned NOT NULL DEFAULT '0',
`name` varchar(50) DEFAULT NULL,
`hash` varchar(32) NOT NULL,
`hash_generated` int(11) NOT NULL,
PRIMARY KEY (`username`)

Register.php

<?php
include("include/session.php");
/**
* The user is already logged in, not allowed to register.
*/
if($session->logged_in){
echo "<h1>Registered</h1>";
echo "<p>We're sorry <b>$session->username</b>, but you've already registered. "
."<a href=\"main.php\">Main</a>.</p>";
}
/**
* The user has submitted the registration form and the
* results have been processed.
*/
else if(isset($_SESSION['regsuccess'])){
/* Registration was successful */
if($_SESSION['regsuccess']){
echo "<h1>Registered!</h1>";
if(EMAIL_WELCOME){
echo "<p>Thankyou <b>".$_SESSION['reguname']."</b>, you have been sent a confirmation email which should be arriving shortly. Please confirm your registration before you continue.<br />Back to <a href='main.php'>Main</a></p>";
}else{
echo "<p>Thank you <b>".$_SESSION['reguname']."</b>, your information has been added to the database, "
."you may now <a href=\"main.php\">log in</a>.</p>";
}
}
/* Registration failed */
else{
echo "<h1>Registration Failed</h1>";
echo "<p>We're sorry, but an error has occurred and your registration for the username <b>".$_SESSION['reguname']."</b>, "
."could not be completed.<br>Please try again at a later time.</p>";
}
unset($_SESSION['regsuccess']);
unset($_SESSION['reguname']);
}
/**
* The user has not filled out the registration form yet.
* Below is the page with the sign-up form, the names
* of the input fields are important and should not
* be changed.
*/
else{
?>

<h1>Register</h1>
<form action="process.php" method="POST">
<p>Username:</p> 
<?php echo $form->error("user"); ?>
<input type="text" name="user" maxlength="18" value="<?php echo $form->value("user"); ?>">
<p>Password:</p>
<?php echo $form->error("pass"); ?>
<input type="password" name="pass" value="<?php echo $form->value("pass"); ?>">
<p>Email:</p>
<?php echo $form->error("email"); ?>
<input type="text" name="email" value="<?php echo $form->value("email"); ?>">
<input type="hidden" name="fav_continent" value="Default">
<input type="hidden" name="fav_colour" value="Default">
<input type="hidden" name="subjoin" value="1">
<input type="submit" value="Register">
</form>

<?php
}
?>

Process.php

<?php
include("include/session.php");

class Process
{
/* Class constructor */
function Process(){
global $session;
/* User submitted login form */
if(isset($_POST['sublogin'])){
$this->procLogin();
}
/* User submitted registration form */
else if(isset($_POST['subjoin'])){
$this->procRegister();
}
/* User submitted edit account form */
else if(isset($_POST['subedit'])){
$this->procEditAccount();
}
else if(isset($_POST['subConfirm'])){
$this->procSendConfirm();
}
else if(isset($_POST['login_with_hash'])){
$this->procHashLogin($_POST['hash']);
}
/**
* The only other reason user should be directed here
* is if he wants to logout, which means user is
* logged in currently.
*/
else if($session->logged_in){
$this->procLogout();
}
}

/**
* procRegister - Processes the user submitted registration form,
* if errors are found, the user is redirected to correct the
* information, if not, the user is effectively registered with
* the system and an email is (optionally) sent to the newly
* created user.
*/
function procRegister(){
global $session, $form;
$_POST = $session->cleanInput($_POST);
/* Registration attempt */
$retval = $session->register($_POST['user'], $_POST['pass'], $_POST['email'], $_POST['fav_continent'], $_POST['fav_colour']);

/* Registration Successful */
if($retval == 0){
$_SESSION['reguname'] = $_POST['user'];
$_SESSION['regsuccess'] = true;
header("Location: ".$session->referrer);
}
/* Error found with form */
else if($retval == 1){
$_SESSION['value_array'] = $_POST;
$_SESSION['error_array'] = $form->getErrorArray();
header("Location: ".$session->referrer);
}
/* Registration attempt failed */
else if($retval == 2){
$_SESSION['reguname'] = $_POST['user'];
$_SESSION['regsuccess'] = false;
header("Location: ".$session->referrer);
}
}
};

/* Initialize process */
$process = new Process;

?>

Database.php

<?php
include("constants.php");

define("DB_SERVER", "localhost");
define("DB_USER", "questers_dbuser1");
define("DB_PASS", "mallz123");
define("DB_NAME", "questers_db1");

class MySQLDB
{
var $connection; //The MySQL database connection
var $num_active_users; //Number of active users viewing site
var $num_active_guests; //Number of active guests viewing site
var $num_members; //Number of signed-up users
/* Note: call getNumMembers() to access $num_members! */

/* Class constructor */
function MySQLDB(){
/* Make connection to database */
$this->connection = mysql_connect(DB_SERVER, DB_USER, DB_PASS) or die(mysql_error());
mysql_select_db(DB_NAME, $this->connection) or die(mysql_error());

/**
* Only query database to find out number of members
* when getNumMembers() is called for the first time,
* until then, default value set.
*/
$this->num_members = -1;

if(TRACK_VISITORS){
/* Calculate number of users at site */
$this->calcNumActiveUsers();

/* Calculate number of guests at site */
$this->calcNumActiveGuests();
}
}

/**
* confirmUserPass - Checks whether or not the given
* username is in the database, if so it checks if the
* given password is the same password in the database
* for that user. If the user doesn't exist or if the
* passwords don't match up, it returns an error code
* (1 or 2). On success it returns 0.
*/
function confirmUserPass($username, $password){
/* Add slashes if necessary (for query) */
if(!get_magic_quotes_gpc()) {
$username = addslashes($username);
}

/* Verify that user is in database */
$q = sprintf("SELECT password FROM ".TBL_USERS." where username = '%s'",
mysql_real_escape_string($username));
$result = mysql_query($q, $this->connection);
if(!$result || (mysql_numrows($result) < 1)){
return 1; //Indicates username failure
}

/* Retrieve password from result, strip slashes */
$dbarray = mysql_fetch_array($result);
$dbarray['password'] = stripslashes($dbarray['password']);
$password = stripslashes($password);

/* Validate that password is correct */
if($password == $dbarray['password']){
return 0; //Success! Username and password confirmed
}
else{
return 2; //Indicates password failure
}
}

/**
* confirmUserID - Checks whether or not the given
* username is in the database, if so it checks if the
* given userid is the same userid in the database
* for that user. If the user doesn't exist or if the
* userids don't match up, it returns an error code
* (1 or 2). On success it returns 0.
*/
function confirmUserID($username, $userid){
/* Add slashes if necessary (for query) */
if(!get_magic_quotes_gpc()) {
$username = addslashes($username);
}

/* Verify that user is in database */
$q = sprintf("SELECT userid FROM ".TBL_USERS." WHERE username= '%s'",
mysql_real_escape_string($username));
$result = mysql_query($q, $this->connection);
if(!$result || (mysql_numrows($result) < 1)){
return 1; //Indicates username failure
}

/* Retrieve userid from result, strip slashes */
$dbarray = mysql_fetch_array($result);
$dbarray['userid'] = stripslashes($dbarray['userid']);
$userid = stripslashes($userid);

/* Validate that userid is correct */
if($userid == $dbarray['userid']){
return 0; //Success! Username and userid confirmed
}
else{
return 2; //Indicates userid invalid
}
}

/**
* usernameTaken - Returns true if the username has
* been taken by another user, false otherwise.
*/
function usernameTaken($username){
if(!get_magic_quotes_gpc()){
$username = addslashes($username);
}
$q = sprintf("SELECT username FROM ".TBL_USERS." WHERE username = '%s'",
mysql_real_escape_string($username));
$result = mysql_query($q, $this->connection);
return (mysql_numrows($result) > 0);
}


/**
* emailTaken - Returns true if the email has
* been taken by another user, false otherwise.
*/
function emailTaken($email){
if(!get_magic_quotes_gpc()){
$email = addslashes($email);
}
$q = sprintf("SELECT email FROM ".TBL_USERS." WHERE email = '%s'",
mysql_real_escape_string($email));
$result = mysql_query($q, $this->connection);
return (mysql_num_rows($result) > 0);
}

/**
* addNewUser - Inserts the given (username, password, email)
* info into the database. Appropriate user level is set.
* Returns true on success, false otherwise.
*/
function addNewUser($username, $password, $email, $userid, $fav_continent, $fav_colour){
$time = time();
/* If admin sign up, give admin user level */
if(strcasecmp($username, ADMIN_NAME) == 0){
$ulevel = ADMIN_LEVEL;
}else{
$ulevel = USER_LEVEL;
}
$q = sprintf("INSERT INTO ".TBL_USERS." VALUES ('%s', '%s', '%s', '%s', '%s', $time, '0', '%s', '%s', '%s', '0', '0')",
mysql_real_escape_string($username),
mysql_real_escape_string($password),
mysql_real_escape_string($userid),
mysql_real_escape_string($ulevel),
mysql_real_escape_string($email),
mysql_real_escape_string($fav_continent),
mysql_real_escape_string($fav_colour));
return mysql_query($q, $this->connection);
}

/**
* updateUserField - Updates a field, specified by the field
* parameter, in the user's row of the database.
*/
function updateUserField($username, $field, $value){
$q = sprintf("UPDATE ".TBL_USERS." SET %s = '%s' WHERE username = '%s'",
mysql_real_escape_string($field),
mysql_real_escape_string($value),
mysql_real_escape_string($username));
return mysql_query($q, $this->connection);
}

/**
* getUserInfo - Returns the result array from a mysql
* query asking for all information stored regarding
* the given username. If query fails, NULL is returned.
*/
function getUserInfo($username){
$q = sprintf("SELECT * FROM ".TBL_USERS." WHERE username = '%s'",
mysql_real_escape_string($username));
$result = mysql_query($q, $this->connection);
/* Error occurred, return given name by default */
if(!$result || (mysql_numrows($result) < 1)){
return NULL;
}
/* Return result array */
$dbarray = mysql_fetch_array($result);
return $dbarray;
}

function getUserInfoFromHash($hash){
$q = sprintf("SELECT * FROM ".TBL_USERS." WHERE hash = '%s'",
mysql_real_escape_string($hash));
$result = mysql_query($q, $this->connection);
if(!$result || (mysql_num_rows($result) < 1)){
return NULL;
}
$dbarray = mysql_fetch_array($result);
return $dbarray;
}

/**
* query - Performs the given query on the database and
* returns the result, which may be false, true or a
* resource identifier.
*/
function query($query){
return mysql_query($query, $this->connection);
}
};

/* Create database connection */
$database = new MySQLDB;

?>

Form.php

 

<?php

class Form
{
var $values = array(); //Holds submitted form field values
var $errors = array(); //Holds submitted form error messages
var $num_errors; //The number of errors in submitted form

/* Class constructor */
function Form(){
/**
* Get form value and error arrays, used when there
* is an error with a user-submitted form.
*/

if(isset($_SESSION['value_array']) && isset($_SESSION['error_array'])){
$this->values = $_SESSION['value_array'];
$this->errors = $_SESSION['error_array'];
$this->num_errors = count($this->errors);

unset($_SESSION['value_array']);
unset($_SESSION['error_array']);
}
else{
$this->num_errors = 0;
}
}

/**
* setValue - Records the value typed into the given
* form field by the user.
*/

function setValue($field, $value){
$this->values[$field] = $value;
}

/**
* setError - Records new form error given the form
* field name and the error message attached to it.
*/

function setError($field, $errmsg){
$this->errors[$field] = $errmsg;
$this->num_errors = count($this->errors);
}

/**
* value - Returns the value attached to the given
* field, if none exists, the empty string is returned.
*/

function value($field){
if(array_key_exists($field,$this->values)){
return htmlspecialchars(stripslashes($this->values[$field]));
}else{
return "";
}
}

/**
* error - Returns the error message attached to the
* given field, if none exists, the empty string is returned.
*/

function error($field){
if(array_key_exists($field,$this->errors)){
return "<font size=\"2\" color=\"#ff0000\">".$this->errors[$field]."</font>";
}else{
return "";
}
}

/* getErrorArray - Returns the array of error messages */
function getErrorArray(){
return $this->errors;
}
};

?>

 

 

Session.php

<?php
include("database.php");
include("form.php");

class Session
{
var $username; //Username given on sign-up
var $userid; //Random value generated on current login
var $userlevel; //The level to which the user pertains
var $time; //Time user was last active (page loaded)
var $logged_in; //True if user is logged in, false otherwise
var $userinfo = array(); //The array holding all user info
var $url; //The page url current being viewed
var $referrer; //Last recorded site page viewed

function Session(){
$this->time = time();
$this->startSession();
}

function startSession(){
global $database; //The database connection
session_start(); //Tell PHP to start the session

/**
* Set guest value to users not logged in, and update
* active guests table accordingly.
*/
if(!$this->logged_in){
$this->username = $_SESSION['username'] = GUEST_NAME;
$this->userlevel = GUEST_LEVEL;
$database->addActiveGuest($_SERVER['REMOTE_ADDR'], $this->time);
}
/* Update users last active timestamp */
else{
$database->addActiveUser($this->username, $this->time);
}

/* Remove inactive visitors from database */
$database->removeInactiveUsers();
$database->removeInactiveGuests();

/* Set referrer page */
if(isset($_SESSION['url'])){
$this->referrer = $_SESSION['url'];
}else{
$this->referrer = "/";
}

/* Set current url */
$this->url = $_SESSION['url'] = $_SERVER['PHP_SELF'];
}

function register($subuser, $subpass, $subemail, $subfav_continent, $subfav_colour){

global $database, $form, $mailer; //The database, form and mailer object

/* Username error checking */
$field = "user"; //Use field name for username
if(!$subuser || strlen($subuser = trim($subuser)) == 0){
$form->setError($field, "* Username not entered");
}
else{
/* Check if username is already in use */
else if($database->usernameTaken($subuser)){
$form->setError($field, "* Username already in use");
}
}

/* Password error checking */
$field = "pass"; //Use field name for password
if(!$subpass){
$form->setError($field, "* Password not entered");
}
else{
/* Spruce up password and check length*/
$subpass = stripslashes($subpass);
if(strlen($subpass) < 4){
$form->setError($field, "* Password too short");
}

}

/* Email error checking */
$field = "email"; //Use field name for email
if(!$subemail || strlen($subemail = trim($subemail)) == 0){
$form->setError($field, "* Email not entered");
}
else{
/* Check if valid email address */
if(filter_var($subemail, FILTER_VALIDATE_EMAIL) == FALSE){
$form->setError($field, "* Email invalid");
}
/* Check if email is already in use */
if($database->emailTaken($subemail)){
$form->setError($field, "* Email already in use");
}

$subemail = stripslashes($subemail);
}

$randid = $this->generateRandID();

/* Errors exist, have user correct them */
if($form->num_errors > 0){
return 1; //Errors with form
}
/* No errors, add the new account to the */
else{
if($database->addNewUser($subuser, md5($subpass), $subemail, $randid, $subfav_continent, $subfav_colour)){
if(EMAIL_WELCOME){
$mailer->sendWelcome($subuser,$subemail,$subpass,$randid);
}
return 0; //New user added succesfully
}else{
return 2; //Registration attempt failed
}
}
}


/**
* generateRandID - Generates a string made up of randomized
* letters (lower and upper case) and digits and returns
* the md5 hash of it to be used as a userid.
*/
function generateRandID(){
return md5($this->generateRandStr(16));
}

/**
* generateRandStr - Generates a string made up of randomized
* letters (lower and upper case) and digits, the length
* is a specified parameter.
*/
function generateRandStr($length){
$randstr = "";
for($i=0; $i<$length; $i++){
$randnum = mt_rand(0,61);
if($randnum < 10){
$randstr .= chr($randnum+48);
}else if($randnum < 36){
$randstr .= chr($randnum+55);
}else{
$randstr .= chr($randnum+61);
}
}
return $randstr;
}

function cleanInput($post = array()) {
foreach($post as $k => $v){
$post[$k] = trim(htmlspecialchars($v));
}
return $post;
}
};


/**
* Initialize session object - This must be initialized before
* the form object because the form uses session variables,
* which cannot be accessed unless the session has started.
*/
$session = new Session;

/* Initialize form object */
$form = new Form;

?>
Link to comment
Share on other sites

Um, yeah. I don't think you are going to get someone to parse through all of that code to try and figure out the problem. It seems you are simply checking a session value to determine whether registration succeeded or not

 

if($_SESSION['regsuccess']){

 

But, the code has some logic problems. take this for example:

 

else if(isset($_SESSION['regsuccess'])){
/* Registration was successful */
if($_SESSION['regsuccess']){

There is an elseif() to check if that variable exists. Then there is an immediate if() condition after that to check the same exact thing. That is not the cause of the problem you are experiencing - but it shows that the logic is flawed and that there are likely bigger issues.

 

I think you first need to go back and map out the logic on a piece of paper or in a flowchart. Then revise your code for that logical workflow.

 

As to knowing why registration fails. You need to look at all the conditions that would cause the value to not be set. Add error handling to log the errors some way. That way you can find out "why" the registration failed.

Link to comment
Share on other sites

in addition to what Psycho stated, your error handling needs to produce a user error message - tell the user specifically what they did that didn't work, if it's something they can correct (missing data, incorrect formated data, username/email already in use...) or output a generic failure message if the problem is an error in the application (database query errors...) and generate an application error message that contains the exact information about who, what, when, where, and why something failed, that you log on a live server and display when developing/debugging your code.

 

if you use trigger_error() to handle the application error message, it makes use of php's error_reporting/display_errors/log_errors settings so you can control what happens with the message by altering the same settings that control what happens with php detected errors.

 

 

edit: here's probably what the vague failure message is due to. the following, being used after several of the queries,  is mistaken logic -

if(!$result || (mysql_numrows($result) < 1)){
return 1; //Indicates username failure
}

a false $result i.e. the !$result, means that the query failed due to an error of some kind, a connection error, a problem with the sql syntax,  a problem with the table/columns... only the mysql_numrows() value means that the query didn't match any rows. those two different conditions need to be handled separately as they mean something different.

Edited by mac_gyver
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • 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.