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…
Any thoughts or suggestions? Here’s the code:
MYSQL Code
[php]
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
)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
[/php]
Register.php
[php]
<?php include("include/session.php"); /** * The user is already logged in, not allowed to register. */ if($session->logged_in){ echo "Registered
"; echo "We're sorry $session->username, but you've already registered. " ."Main.
"; } /** * 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 "Registered!
"; if(EMAIL_WELCOME){ echo "Thankyou ".$_SESSION['reguname'].", you have been sent a confirmation email which should be arriving shortly. Please confirm your registration before you continue.
Back to Main
Thank you ".$_SESSION['reguname'].", your information has been added to the database, " ."you may now log in.
"; } } /* Registration failed */ else{ echo "Registration Failed
"; echo "We're sorry, but an error has occurred and your registration for the username ".$_SESSION['reguname'].", "
."could not be completed.
Please try again at a later time.
Register
Username:
<?php echo $form->error("user"); ?> ">Password:
<?php echo $form->error("pass"); ?> ">Email:
<?php echo $form->error("email"); ?> "> <?php } ?>[/php]
Process.php
[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; ?>[/php]
Database.php
[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; ?>[/php]
Form.php
[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 "".$this->errors[$field].""; }else{ return ""; } } /* getErrorArray - Returns the array of error messages */ function getErrorArray(){ return $this->errors; } }; ?>[/php]
Session.php
[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; ?>[/php]