I\'m currently working on a registration system and ran into some problem.
I\'ll start with pasting a simplified version of the code before:
session_start(
got bored. this is not for internet points.
<?php
// create table user (userid int auto_increment primary key, username varchar(60), password varchar(60));
// alter table user add constraint uc_user_username unique (username);
var_dump($_POST);
$user = isset($_POST['username']) ? trim($_POST['username']) : '';
$pass = isset($_POST['password']) ? trim($_POST['password']) : '';
$pass2 = isset($_POST['confirm']) ? trim($_POST['password2']) : '';
$action = isset($_POST['action_type']) ? $_POST['action_type'] : '';
if (empty($_POST)) {
// nothing posted
}
else {
if (empty($user)) {
error('you did not provide a username');
}
elseif (empty($pass)) {
error('you did not provide a password');
}
else {
$mysqli = mysqli_connect('localhost','root','','test')
or die('Error ' . mysqli_error($link));
if ($action=='new_user') {
$userdata = get_user_info($mysqli,$user);
if ($userdata) {
error('user already exists');
}
else {
$validpass = validate_password($pass);
if ($validpass && $pass==$pass2){
if (make_new_user($mysqli,$user,$pass)) {
print "<br/>new user created<br/><br/>";
}
}
else error('passwords did not match');
}
}
elseif ($action=='login_user') {
$verified = verify_credentials($mysqli,$user,$pass);
if ($verified) {
print "<br/>user logged in<br/><br/>";
}
}
elseif ($action=='update_pass') {
$verified = verify_credentials($mysqli,$user,$pass);
$validpass = validate_password($pass);
if ($verified && $validpass && $pass!=$pass2) {
if (update_password($mysqli,$user,$pass,$pass2)) {
print "<br/>new user created<br/><br/>";
}
}
else error('cannot update to same password');
}
$mysqli->close();
}
}
function error($message) {
print "<br/>$message<br/><br/>";
}
function update_password($mysqli,$user,$pass,$pass2) {
$hash = password_hash($pass, PASSWORD_BCRYPT);
$stmt = $mysqli->prepare('update user set password = ? where username = ?');
$stmt->bind_param('ss',$user,$hash);
$stmt->execute();
$msql_error = $mysqli->error;
$updated = !(empty($msql_error));
error($msql_error); // for debugging only
return $updated;
}
function make_new_user($mysqli,$user,$pass) {
$userid = false;
$hash = password_hash($pass, PASSWORD_BCRYPT);
$stmt = $mysqli->prepare('insert into user (username,password) values (?,?)');
$stmt->bind_param('ss',$user,$hash);
$stmt->execute();
$msql_error = $mysqli->error;
if (empty($msql_error)) {
$userid = $mysqli->insert_id;
}
else error($msql_error); // for debugging only
return $userid;
}
// really, this should be done with javascript instantaneously
function validate_password($pass) {
$error = false;
if (strlen($pass) < 8) {
error('please enter a password with at least 8 characters');
}
elseif (!preg_match('`[A-Z]`', $pass)) {
error('please enter at least 1 capital letter');
}
else $error = true;
return $error;
}
function verify_credentials($mysqli,$user,$pass) {
$row = get_user_info($mysqli,$user);
$verified = false;
if ($row) {
if (password_verify($pass, $row['pass'])) {
$verified = true;
}
}
else error('username and password did not match');
return $verified;
}
function get_user_info($mysqli,$user) {
$row = array();
$stmt = $mysqli->prepare('select userid, username, password
from user
where username = ?');
$stmt->bind_param('s',$user);
$stmt->execute();
$stmt->bind_result($row['userid'],$row['user'],$row['pass']);
if (!$stmt->fetch()) $row = false;
$stmt->close();
return $row;
}
?>
<body>
<form action='?' method='post'>
<table id='input_table'>
<tr><td><span>username </span></td><td><input id='username' name='username' type='text' value='<?php echo $user ?>'></td></tr>
<tr><td><span>password </span></td><td><input id='password' name='password' type='text' value='<?php echo $pass ?>'></td></tr>
<tr><td><span>password2</span></td><td><input id='password2' name='password2' type='text' value='<?php echo $pass2 ?>'></td></tr>
<tr><td> </td><td> </td></tr>
<tr><td colspan=2>this just picks the action for testing... you wouldn't keep it around</td></tr>
<tr><td><input type='radio' name='action_type' value='new_user' <?php echo $action=='new_user'?'checked':'' ?>>New User</td></tr>
<tr><td><input type='radio' name='action_type' value='login_user' <?php echo $action=='login_user'?'checked':'' ?>>Logging In</td></tr>
<tr><td><input type='radio' name='action_type' value='update_pass' <?php echo $action=='update_pass'?'checked':'' ?>>New Password</td></tr>
<tr><td> </td><td> </td></tr>
<tr><td colspan=2><input id='submit' name='submit' type='submit'/></td></tr>
</form>
</body>
// error = 0 means no error found you can continue to upload...
if ($_FILES['file']['error'] == 0) {
}
Here are all of the errors explained: http://php.net/manual/en/features.file-upload.errors.php
UPLOAD_ERR_OK
Value: 0; There is no error, the file uploaded with success.
UPLOAD_ERR_INI_SIZE
Value: 1; The uploaded file exceeds theupload_max_filesize
directive in php.ini.
UPLOAD_ERR_FORM_SIZE
Value: 2; The uploaded file exceeds theMAX_FILE_SIZE
directive that was specified in the HTML form.
UPLOAD_ERR_PARTIAL
Value: 3; The uploaded file was only partially uploaded.
UPLOAD_ERR_NO_FILE
Value: 4; No file was uploaded.
UPLOAD_ERR_NO_TMP_DIR
Value: 6; Missing a temporary folder. Introduced in PHP 5.0.3.
UPLOAD_ERR_CANT_WRITE
Value: 7; Failed to write file to disk. Introduced in PHP 5.1.0.
UPLOAD_ERR_EXTENSION
Value: 8; A PHP extension stopped the file upload. PHP does not provide a way to ascertain which extension caused the file upload to stop; examining the list of loaded extensions with phpinfo() may help. Introduced in PHP 5.2.0.
To validate input fields
if(empty($_POST['name'])&&empty($_POST['password'])){
//fields empty show error here
}else if (is_numeric($username[0])){
echo 'First character must be a letter';
}
else if (!preg_match('/^[a-zA-Z0-9]+$/', $username)) {
echo 'Only letters and numbers are allowed';
}else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo 'Invalid email address.';
}else if(!preg_match("/^[\pL\s,.'-]+$/u", $name)) {
echo 'Invalid name.';
}
Your question isn't exactly clear, nor is your code which is also incomplete (where is the form?).
You seem to be at an early stage of learning the form handling, and likely would benefit from further reading and testing before you ask specific questions.
Here are some starters:
http://en.wikipedia.org/wiki/Post/Redirect/Get
What's the best method for sanitizing user input with PHP?
The definitive guide to form-based website authentication
I'll give some info anyway, as have some free time.
For example, your first if
checks if session IS set, if TRUE redirect to notLoggedIn. Are you sure this is intentional? Either they're logged in, echo message to suit, or not and so show the reg page (most sites show a login and reg on the same page, for convenience for all scenarios).
As this is a registration form, surely you meant if IS logged in then redirect to YouAreAlreadyLoggedIn?
In fact, I'd just exit a message "You are already logged in" then stop the script.
The problem is the fact that it runs everything at once and just redirects me to index.php.
That's because it has no other option, as at the end of your script after XYZ it redirects to index.php.
If you do not want it to do this then change it. Either don't redirect, handle the entire process more constructively, or exit at some point you need it to (like form errors).
How do I make sure it first of all checks if the form has been submitted before running.
I don't see a form, so don't know exactly what you are doing to advise.
Ideally you'd use the PRG (Post Redirect Get).
http://en.wikipedia.org/wiki/Post/Redirect/Get
I've edited your script to make this an answer to the question, and tidied it up a little.
e.g. in your script, specifically at the top, you don't need the else
as there's an exit()
in the if
. When the if
returns true, the script will stop, otherwise (with or without an else
) it will continue.
The code:
session_start();
if (isset($_SESSION['logged_in']))
{
exit('You are already logged in');
}
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
if ( strlen($POST['field_name']) < 4 )
{
exit('Minimum 4 chars required');
}
elseif ( strlen($POST['field_name']) > 20 )
{
exit('Max of 20 chars allowed');
}
elseif ( preg_match("/^[A-z0-9]+$/", $POST['field_name']) != 1 )
{
exit('Invalid chars - allowed A-z and 0-9 only');
}
else
{
// Not sure what you want here
// If all ok (no errors above)
// then sanatise the data and insert into DB
}
}
As for entering into the DB, you need much more checking and handling of the entire process before you just allow the DB stuff to run.
Not sure why you redirect to index.php. You'd then need to handle form submission results in index.php to tell user you are registered. On the form page, tell them the errors they have in the fields, or echo out the success message and what happens next (i.e. go to your account page, or (hopefully) confirm the email you sent before logging in).
As for the validation checks in the POSTed form data, it's entirely up to you what you need. But I've given you some very basic to go on. Make sure your max set in the form matches the database column allowance, or if (eg) DB varchar is set to 15 and you allow users to enter 20, the data they enter will be truncated, and they'll register, but never be able to login (or some other data will be broken, their name/username etc).