Here is an example showing the suggestions above. Note: I have changed the database table name, so that it indicates the meaning of the data, this example uses the php PDO database extension, not the mysqli extension, and since this code expects the passwords to be hashed, your registration code needs to be modified to use the password_hash() function and then delete and re-register any users.
PHP Code:
<?php
// start/resume any session
session_start();
// helper functions - either define these in a file and require the file or define them in-line in the main code
// user login/authentication will use a session variable to indicate/identify who the logged in user is
// test/get the logged in user's id - the user id is a true value, so this function returns a true value, the id, for a logged in user, or a false value, if the user is not logged in
function logged_in()
{
return isset($_SESSION['user_id']) ? $_SESSION['user_id'] : false;
}
// the dynamic values being output in the html document need to be converted to html entities in case they contain any characters that have meaning in html markup
// apply htmlentities to a general value
function _ent($val)
{
return htmlentities($val,ENT_QUOTES,CHAR_ENCODING);
}
// return an element of a supplied array - used for both the $data and $errors arrays
function _data($idx,$data)
{
return isset($data[$idx]) ? $data[$idx] : '';
}
// require either configuration values (the connection credentials) or the whole connection code
// this example uses the php PDO extension, not the msyqli extension
require 'pdo_connection.php';
$errors = []; // define an array to hold errors
$data = []; // define an array to hold a working/trimmed copy of the submitted form data. for this example, of submitting new data, this is not absolutely necessary, but if you were editing existing data, you would need this. to make the code general purpose, just go ahead and define and use a variable for this.
// from processing code - since this is the only form processing in this example, for logging in, it will only be executed if the visitor is not already logged in
if(!logged_in() && $_SERVER['REQUEST_METHOD'] == 'POST')
{
$data = array_map('trim',$_POST); // get a trimmed copy of all 1st level (non-array) data
// validate the inputs
if($data['email'] == '')
{
$errors['email'] = "Email is required.";
}
if($data['password'] == '')
{
$errors['password'] = "Password is required.";
}
// if no errors, use the submitted data
if(empty($errors))
{
//create and issue the query
$sql = "SELECT id, password FROM users WHERE email = ?"; // your table should be named to indicate the meaning of the data stored in it
$stmt = $pdo->prepare($sql);
$stmt->execute([$data['email']]);
// attempt to fetch the data from the query - for a single row of data, this accomplishes the same as checking the number of rows, followed by a fetch statement
if(!$row = $stmt->fetch())
{
// no row found, the email doesn't match
$errors['login'] = "The email/password isn't valid.";
}
else
{
// found the email, check the password
if(!password_verify($data['password'],$row['password']))
{
// password doesn't match
$errors['login'] = "The email/password isn't valid.";
}
else
{
// password matched - set the session variable with the user's id
$_SESSION['user_id'] = $row['id'];
}
}
}
// if no errors, the form processing successfully ran
if(empty($errors))
{
// you can redirect to the exact same url of this page to improve the UX...
}
// if there are any errors, continue to display the page
}
// get/produce the content for the page
// get user's data
$user = false;
if($user_id = logged_in())
{
$sql = "SELECT username FROM users WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$user_id]);
$user = $stmt->fetch();
}
// the main content
$display_block = '';
if(logged_in())
{
$display_block = "
<p>". _ent($user['username']) ." is authorized! </p>
<p>Authorized Users' Menu: </p>
<ul>
<li><a href='submitReview.php'>Click here to submit a review! </a></li>
</ul>
";
}
if(!logged_in())
{
$display_block = "
<form method='post'>
Email: <input type='email' name='email' value='". _ent(_data('email',$data)) ."'><br>
Password: <input type='password' name='password' value='". _ent(_data('password',$data)) ."'><br>
<input type='submit'></form>
";
}
// the html document
?>
<!DOCTYPE html>
<html>
<head>
<title>User Login</title>
</head>
<body>
<?php
// display any errors
if(!empty($errors))
{
echo "<p>".implode('<br>',$errors)."</p>";
}
// display the main content
echo $display_block;
?>
</body>
</html>
An example of the pdo_connection.php code -
PHP Code:
<?php
define('DB_HOST','localhost');
define('DB_NAME','your database name');
define('DB_USER','your database username');
define('DB_PASS','your database password');
define('DB_ENCODING', 'utf8'); // db character encoding
define('CHAR_ENCODING','UTF-8'); // document/page character encoding
$pdo = new pdo("mysql:host=".DB_HOST.";dbname=".DB_NAME.";charset=".DB_ENCODING,DB_USER,DB_PASS);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // set the error mode to exceptions
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES,false); // run real prepared queries
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC); // set default fetch mode to assoc
Bookmarks