I have a profile page, function for the edit and a check function for the edit.
profile page:
if (isset($_POST['edit']) && $_POST['edit'] === 'Edit') {
$errorMsgs = $user->validateUpdate($_POST);
if (empty($errorMsgs)) {
$id = $_POST['id'];
$username = $_POST['username'];
$email = $_POST['email'];
$user->updateProfile($username,$email,$id);
echo 'edited';
exit;
}
foreach ($errorMsgs as $msg) {
echo '<li>'. $msg. '</li>';
}
}
while ($row = mysqli_fetch_assoc($result)) {
?>
<form action="<?php $_SERVER['PHP_SELF'];?>" method="POST">
<input type="hidden" name="id" value="<?php echo $row['id']; ?>" />
Username<br>
<input type="text" name="username" value="<?php echo $row['username']; ?>" /><br>
Email<br>
<input type="text" name="email" value="<?php echo $row['email']; ?>" /><br>
<input name="edit" type="submit" value="Edit"/>
</form>
<?php }
?>
Update function:
function updateProfile($username,$email,$id){
$con = new Core();
$con->connect();
$username = trim(strtolower($username));
$username = str_replace(' ', '', $username);
$sql = 'UPDATE users SET username = ?, email = ? where id = ?';
if ($stmt = $con->myconn->prepare($sql))
{
$stmt->bind_param('ssi', $username, $email, $id);
$stmt->execute();
$stmt->close();
}
else{
die("errormessage: " . $con->myconn->error);
}
}
Check function:
function validateUpdate(array $userDetails)
{
$con = new Core();
$con->connect();
$errmsg_arr = array();
foreach($userDetails as $key => $value) {
if (empty($value)) {
$errmsg_arr[] = ucwords($key) . " field is required";
}
}
if (!empty($userDetails['edit'])) {
if (!empty($userDetails['email']) && !filter_var($userDetails['email'], FILTER_VALIDATE_EMAIL)) {
$errmsg_arr[] = "the provided email is not a valid email address";
}
$sqlu = "SELECT username FROM users WHERE username = ?";
if($stmt = $con->myconn->prepare($sqlu)){
$stmt->bind_param('s', $_POST['username']);
$stmt->execute();
}
if($stmt->fetch() > 0){
$errmsg_arr[] = "Username already exists!";
$stmt->close();
}
$sqle = "SELECT email FROM users WHERE email = ?";
if($stmt = $con->myconn->prepare($sqle)){
$stmt->bind_param('s', $_POST['email']);
$stmt->execute();
}
if($stmt->fetch() > 0){
$errmsg_arr[] = "Email already exists!";
$stmt->close();
}
}
return $errmsg_arr;
}
Everything works perfect. But there's a flaw in this check.
Someone goes to their profile.
The person tries to edit details, edits it all: code echo's "succesfully edited".
But if the person tries to edit Email only instead of all details, gets the error message that the "Username value" already exists.
Now my question: How would I let it not check on the username value if it isn't edited? Or email value?
Thanks in advance!
you would exclude the user that's logged in from the query. While doing the login you would save the users id in a session variable. You can use this variable for preventing the queries from checking against the user itself
$sqlu = "SELECT username FROM users WHERE username = ? AND id != '".$_SESSION['user_id']."'";
$sqle = "SELECT email FROM users WHERE email = ? AND id != '".$_SESSION['user_id']."'";
That should fix your issue! More info on session variables
Related
I have a script that adds an email address and password to a table. I first search to see if the email address exists in the table. If it does, I give an error message. If it does not, I add the record.
Then, using mysqli_insert_id(), I run another query to update the record I just added, encrypting the password with md5.
But every time I run it, the record is added, but the password does not get updated with the md5 version of the password. I have echo'd the query and it shows that it should be updating the password with the encryption, but it doesn't. Any ideas?
<?php
session_start();
error_reporting(E_ALL);
if (array_key_exists("submit", $_POST)) {
$link = mysqli_connect("localhost", "eits_Admin", "WebSpinner1", "EITS_Sandbox");
if (!$link) {
die("Database connection error");
}
$error = '';
if (!$_POST['email']) {
$error .= "<br/>An email address is required";
}
if (!$_POST['password']) {
$error .= "<br/>A password is required";
}
if ($error != "") {
$error = "There were errors in your form - ".$error;
} else {
$query = "select id from secretdiary
where email = '".mysqli_real_escape_string($link, $_POST['email'])
."' limit 1";
// echo $query;
$result = mysqli_query($link, $query);
if (mysqli_num_rows($result) > 0) {
$error = "That email address is not available.";
} else {
$query = "insert into secretdiary
(email,password)
values ('" . mysqli_real_escape_string($link, $_POST['email'])
. "', '"
. mysqli_real_escape_string($link, $_POST['password']) . "')";
if (!mysqli_query($link, $query)) {
$error = "Could not sign you up at this time. Please try again later.";
} else {
$encPass = md5(md5(mysqli_insert_id($link)) . $_POST['password']);
$query = "update secretdiary
set password = '" . $encPass
. "' where id = " . mysqli_insert_id($link) . " limit 1";
echo $query;
$result = mysqli_query($link,$query);
echo "Sign up successful.";
}
}
}
}
?>
<div id="error"><? echo $error; ?></div>
<form method="post">
<input type="email" name="email" placeholder= "Your Email">
<input type="password" name="password" placeholder="Password">
<input type="checkbox" name="stayLoggedIn" value=1>
<input type="submit" name="submit" value="Sign Up!">
</form>
You've got a lot of lines of code for a relatively simple process. Personally your form error handling such as if it's empty (in this case) can be remedied by adding required at the end of each HTML form input element (This is what I'd do)
Secondly, md5 isn't safe for hashing passwords (you're hashing a password not encrypting it)
Thirdly here's a way to hash the password from the form using Bcrypt which is much better than using md5 hashing. So do whatever error checking you need to do before like counting the usernames and if row > 0 die('username exists) Example of full code at base using PDO
When checking the users login simply use password_verify() function to do so
Tidy code helps people on SO understand what your problem is and is generally nicer to read. I know you may just be looking for something that 'Does the job' But it helps you when debugging and us when you're asking for help.
I'm going to give you a way that is marginally more secure than your one.
index.php
<form method="post" id="regform" action="register.php">
<input type="text" name="username" placeholder="Enter your email Address"required/>
<input type="password" name="password" placeholder="Enter your password" required/>
<input type="submit" class="indexbttn" id="indexbttn" name="enter"value="enter"/>
</form>
connect.php
<?php
$servername = "localhost";
$dbusername = "root";
$dbpassword = "root";
$dbname = "fyp";
try{
$pdo = new PDO("mysql:host=$servername;dbname=$dbname",$dbusername, $dbpassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
print "Error! Unable to connect: " . $e->getMessage() . "<br/>";
die();
}
?>
register.php
<?php
session_start();
require_once ('connect.php');
error_reporting(E_ALL);
ini_set('display_errors', 1);
if(isset($_POST['enter'])){
$username = !empty($_POST['username']) ? trim($_POST['username']) : null;
$pass = !empty($_POST['password']) ? trim($_POST['password']) : null;
$check (!filter_var($_POST['username'], FILTER_VALIDATE_EMAIL));
$cnt = "SELECT COUNT(username) AS num FROM users WHERE username = :username";
$stmt = $pdo->prepare($cnt);
$stmt->bindValue(':username', $username);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($row['num'] > 0){
die('That username already exists!');
}
$passHash = password_hash($pass, PASSWORD_BCRYPT, array("cost" => 12));
$insrt = "INSERT INTO users (username, password) VALUES (:username, :password)";
$stmt = $pdo->prepare($insrt);
$stmt->bindValue(':username', $username);
$stmt->bindValue(':password', $passHash);
$result = $stmt->execute();
if($result){
header( "refresh:5;url=index.php" );
echo 'You will be redirected in 5 seconds. If not, click here.';
}
}
?>
login.php
<?php
session_start();
require("connect.php");
if(isset($_POST['enter'])){
$username = !empty($_POST['username']) ? trim($_POST['username']) : null;
$pass = !empty($_POST['password']) ? trim($_POST['password']) : null;
$rtrv = "SELECT username, password, userid FROM users WHERE username = :username";
$stmt = $pdo->prepare($rtrv);
//Bind value.
$stmt->bindValue(':username', $username);
//Execute.
$stmt->execute();
//Fetch row.
$user = $stmt->fetch(PDO::FETCH_ASSOC);
//If $row is FALSE.
if($user === false){
//Could not find a user with that username!
die('Incorrect username');
}
else{
$validPassword = password_verify($pass, $user['password']);
if($validPassword){
$_SESSION['user_id'] = $user['username'];
$_SESSION['logged_in'] = time();
header( "Location: /protected.php" );
die();
} else{
die('Wrong password!');
}
}
}
?>
I am creating reset password system, Iam done with all parts accept last step where updating password and email in users table.
actually where it doesn't update.lol
it says update succes and redirecting to login but doesn't update pasword.
I echoed all steps to see if values are empty it shows all full.
This is my form:
$selector = $_GET["selector"];
$validator = $_GET["validator"];
if(empty($selector) || empty($validator)){
echo "Could not validate request";
}else{
if(ctype_xdigit($selector) !== false && ctype_xdigit($validator) !== false){
?>
<form action="reset-password.inc.php" method="post">
<input type="hidden" name="selector" value="<?php echo $selector; ?>">
<input type="hidden" name="validator" value="<?php echo $validator; ?>">
<input type="password" name="password" placeholder="Yeni şifre girin...">
<input type="password" name="confirm_password" placeholder="Şifre tekrar...">
<input type="submit" name="reset-password-submit" value="Submit">
<a class="btn btn-link" href="welcome.php">Cancel</a>
</form>
<?php
}
}
And this is the codes in submit page:
if(isset($_POST["reset-password-submit"])){
$selector = $_POST["selector"];
$validator = $_POST["validator"];
$password = $_POST["password"];
$confirm_password = $_POST["confirm_password"];
$currentDate = date("U");
if(empty($password) && empty($confirm_password)){
header("Location: create-new-password.php?newpwd=empty");
exit();
}elseif($password != $confirm_password){
header("Location: create-new-password.php?newpwd=passwords-not-same");
exit();
}else{
$sql = "SELECT * FROM pwdreset WHERE pwdResetSelector = :pwdResetSelector AND pwdResetToken = :pwdResetToken AND pwdResetExpires >= :pwdResetExpires";
if($stmt = $pdo->prepare($sql)){
$stmt->bindParam(":pwdResetSelector", $selector, PDO::PARAM_STR);
$stmt->bindParam(":pwdResetToken", $validator, PDO::PARAM_STR);
$stmt->bindParam(":pwdResetExpires", $currentDate, PDO::PARAM_STR);
if($stmt->execute()){
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if($selector !== $row['pwdResetSelector']){
header("Location: create-new-password.php?newpwd=wrongUrlParameters");
exit();
}elseif($validator !== $row['pwdResetToken']){
header("Location: create-new-password.php?newpwd=wrongUrlParameters");
exit();
}else{
$tokenEmail = $row["pwdResetEmail"];
// CHECK IF EMPTY PASS AND EMAIL AND DO UPDATE
if(empty($password) && empty($tokenEmail)){
$sql = "UPDATE users SET password = :password WHERE email=:email";
if($stmt3 = $pdo->prepare($sql)){
$newpwdhash = password_hash($password, PASSWORD_DEFAULT);
$stmt3->bindParam(":password", $newpwdhash, PDO::PARAM_STR);
$stmt3->bindParam(":email", $tokenEmail, PDO::PARAM_STR);
if($stmt3->execute()){
// DELETE FROM PWDRESET TABLE
$sql = "DELETE FROM pwdReset WHERE pwdResetEmail=:pwdResetEmail";
if($stmt4 = $pdo->prepare($sql)){
$stmt4->bindParam(":pwdResetEmail", $tokenEmail, PDO::PARAM_STR);
$stmt4->execute();
header("Location: login.php?newpwd=success");
exit();
}else{
header("Location: create-new-password.php?newpwd=somethingWentWrong");
exit();
}
}else{
echo "Couldnt execute stmt 3";
exit();
}
}else{
echo "error";
exit();
}
}else{
echo "AN ERROR HAPPEND WHILE QUERY STMT 3";
exit();
}
}
}else{
echo "Couldnt execute sql 1";
exit();
}
}else{
echo "prepare sql didnt work 1";
exit();
}
}
}else{
echo "something went wrong";
exit();
}
I want to check using the POSTBACK method i the user exists in mysql table. I studying mysql and i understand it will be removed soon but I cant change at the moment. I want the alert to pop up next to the username text box if it already exists.At the moment it isnt working. I have a similar code for password and password confirmation but i think this differs since i need a query. This is what i have:
<?php
$passErr = $pass1Err = "";
$passw = $passw1 = "";
$userErr="";
if ($_SERVER["REQUEST_METHOD"] == "POST") {
if (empty($_POST["password"])) {
$passErr = "Password is required";
}
if (empty($_POST["passconfirm"])) {
$pass1Err = "Password confirmation is required";
}
if ($_POST['password']!= $_POST['passconfirm'])
{
$passErr = "Passwords must be the same";
$pass1Err = "Passwords must be the same";
}
}
else {
if (isset($_REQUEST["submit"]))
{
if (isset($_POST["submit"]))
{
$firstname = mysql_real_escape_string($_POST["gname"]);
$middlename = mysql_real_escape_string($_POST["mname"]);
$lastname = mysql_real_escape_string($_POST["surname"]);
$user = mysql_real_escape_string($_POST["username"]);
$addy = mysql_real_escape_string($_POST["address"]);
$post = mysql_real_escape_string($_POST["postcode"]);
$sta = mysql_real_escape_string($_POST["state"]);
$telephone = mysql_real_escape_string($_POST["tel"]);
$pass = mysql_real_escape_string($_POST["password"]);
$systemuser= mysql_real_escape_string($_POST["susername"]);
$sql2 = "SELECT username FROM users WHERE username= '$user'";
$rs = mysql_query($sql2, $conn)
or die ('Problem with query' . mysql_error());
$num_rows = mysql_num_rows($rs);
if(isset($_POST['username'])) {
if($num_rows != 0){
$userErr = "Username already exists";
}
}
}
}
mysql_close($conn);
}
?>
this is what i got in the form:
<label>Chosen Username:</label> <input type="text" name="username" value="<?php
echo $userErr;?>"/><span class="error">* <?php echo $userErr;?></span><br />
<label>Password:</label> <input type="password" name="password" value="<?php
echo $passw;?>"/><span class="error">* <?php echo $passErr;?></span><br />
<br />
<label>Password confirmation:</label> <input type="password" name="passconfirm" value="<?php
echo $passw1;?>"/><span class="error">* <?php echo $pass1Err;?></span><br />
To acheive what your looking for, instead of using
$num_rows = mysql_num_rows($rs);
if(isset($_POST['username'])) {
if($num_rows != 0){
$userErr = "Username already exists";
}
}
replace it with
$num_rows = mysql_num_rows($rs);
if(isset($_POST['username'])) {
$userErr = "Username field cannot be empty";
}elseif($num_rows > 0){
$userErr = "Username already exists";
}
That way if the Username field is empty, it will error out. And this will also achieve your goal of checking the database to see if the user exists or not.
You need to know if request with username return something so error messsage else do insert new user,
$sql2 = "SELECT * FROM users WHERE username= '$user'";
$rs = mysql_query($sql2, $conn) or die ('Problem with query' . mysql_error());
if($num_rows=mysql_fetch_array($rs)){
$userErr = "Username already exists";
// ....
} else{
// $SQL = "INSERT INTO users SET ...
}
at the moment my form links to a new page with all of my php code on it. I would like for all of the code to be executed on the same page as it does in this tutorial: http://www.w3schools.com/php/php_form_url_email.asp
I'm having some difficulty understanding exactly how this tutorial manages it. I was thinking maybe it would be possible to store my add.php code in a function and then call it with form action. Is this possible? If not what would be the best way to go about this?
here is my form code:
<form action="add.php" method="post">
<p>
Username: <input type="text" name="Username"><br>
Email: <input type="text" name="Email"><br>
Password: <input type="password" name="Password"><br>
Confirm Password: <input type="password" name="ConfirmPass">
</p>
<p>
<input type="submit">
</p>
</form>
and here is my add.php page:
<?php
$Username = $_POST['Username'];
$Password = $_POST['Password'];
$Email = $_POST['Email'];
$ConfirmPass = $_POST['ConfirmPass'];
$safeUsername = SQLite3::escapeString($Username);
$safePassword = SQLite3::escapeString($Password);
$safeEmail = SQLite3::escapeString($Email);
$safeConfirmPass = SQLite3::escapeString($ConfirmPass);
$hostName = explode('#', $Email);
$database = new PDO('sqlite:maindb.db');
$sql = "SELECT * FROM users WHERE Username = ?";
$result = $database->prepare($sql);
$result->bindParam(1, $safeUsername);
$result->execute();
if($result->fetch()) {
echo "Username " . $safeUsername . " already exists";
}
else {
if (filter_var($safeEmail, FILTER_VALIDATE_EMAIL) && checkdnsrr($hostName[1]) && !empty($safeEmail)) {
if (preg_match("/([\w\-]+\#[\w\-]+\.[\w\-]+)/",$safeEmail)) {
if (!empty($safeUsername) && (preg_match("/^[a-zA-Z ]*$/",$safeUsername)) && !empty($safeUsername)) {
if ($safePassword == $safeConfirmPass && !empty($safePassword)) {
echo $Username . " was successfully added to the database.";
$stm = "INSERT INTO users(Username, Password, Email) VALUES(?,?,?)";
$stmt = $database->prepare($stm);
$stmt->bindParam(1, $safeUsername);
$stmt->bindParam(2, $safePassword);
$stmt->bindParam(3, $safeEmail);
$stmt->execute();
$database = null;
}
else {echo "Passwords do not match"; }
}
else {echo "Invalid Username.";}
}
else {echo "Invalid e-mail address.";}
}
else {echo "Invalid e-mail address.";}
}
?>
Thanks for the help! I appreciate it.
In the tutorial you linked they use
if ($_SERVER["REQUEST_METHOD"] == "POST") {
//your stuff here
//save your form values etc.
}
to check if there has been a post to your page (this can be any page so also the same page). Basically this will check if a POST request has been send to this page. Which will if you use a from with a post method.
As an extra test they also put stuff like
if (empty($_POST["name"])) {
//name is empty print error!
}
in it to check if a field is empty or not.
all you gotta do now is change your action to the same page.
Hello I have a function that checks if my registration details doesn't match in the database, if it does, then return the code.
But every time I return the code, my HTML won't load because it's stopping it from loading.
I want the HTML to be always under the PHP code, for some specific reason (I want the errors to display up to the form, and not under).
This is an example of my function:
function check_available($name, $password, $email)
{
global $pdo;
$check_user = $pdo->prepare("SELECT * FROM users WHERE user_name = :username LIMIT 1");
$check_user->execute( array(':username' => $name) );
$check_email = $pdo->prepare("SELECT * FROM users WHERE user_email = :email LIMIT 1");
$check_email->execute( array(':email' => $email) );
$error = '';
if ($check_user->rowCount())
{
$error .= 'Username already exists!';
return handle_errors($error);
}
else if($check_email->rowCount() && !$check_user->rowCount())
{
$error .= 'Email already exists!';
return handle_errors($error);
}
else
{
return true;
}
}
if (isset($_POST['submit']))
{
$check_in = check_available($name, $password, $email);
if ($check_in == true)
{
echo 'Created account sucessfully!';
}
}
?>
<html>
<form action="register.php" method="POST">
Username: <input type="text" name="username"><br />
Password: <input type="password" name="password"><br />
Email: <input type="text" name="email"><br />
<input type="submit" name="submit">
</form>
</html>
After submiting, (with having a username that already matches in database), the HTML will hide & error will display.
How do I prevent this? is there a trick for that?
There is no point in hiding a form.
Quite contrary, form have to be shown to let a user enter another name.
So, just add an error output to your form - that's all you need
Edit
looks like it's handle_errors() function to blame.
function reg_has_errors($name, $password, $email)
{
global $pdo;
$error = '';
$sql = "SELECT 1 FROM users WHERE user_name = ? LIMIT 1";
$stm = $pdo->prepare($sql);
$stm->execute( array($name) );
if($stm->rowCount())
{
$error .= 'Username already exists!';
}
$sql = "SELECT * FROM users WHERE user_email = ? LIMIT 1";
$stm = $pdo->prepare($sql);
$stm->execute( array($email) );
if($stm->rowCount())
{
$error .= 'Email already exists!';
}
return $error;
}
$errors = '';
if (isset($_POST['submit']))
{
$errors = reg_has_errors($name, $password, $email);
if (!$errors)
{
echo 'Created account sucessfully!';
}
}
echo errors;