I want to record the user ID from the current logged in user who enters data into the form which in turn is recorded to a database table
At present the insert query is running and updating all but the user id..the user id variable is definitely working as I am able to echo it out without any issues on the same page
Code is as follows;
$barcode = $_POST['barcode'];
$weight = $_POST['weight'];
$userId = $_SESSION['userId'];
//error handling begins
// check for any empty inputs.
if (empty($barcode) || empty($weight)) {
header("Location: ../record.php?error=emptyfields&barcode=".$barcode."&weight=".$weight);
exit();
}
//we check if valid barcode entered. In this case ONLY letters and numbers.
else if (!preg_match("/^[a-zA-Z0-9]*$/", $barcode)) {
header("Location: ../record.php?error=invalidbarcode&barcode=".$weight);
exit();
}
// check for an invalid weight. In this case ONLY numbers.
else if (!preg_match("/^[0-9].*$/", $weight)) {
header("Location: ../record.php?error=invalidweight&barcode=".$barcode);
exit();
}
else {
$sql = "INSERT INTO trimrecords (barcode, weight, createdby) VALUES (?,?,?);";
// initialize a new statement using the connection from the dbh.inc.php file.
$stmt = mysqli_stmt_init($conn);
// prepare SQL statement AND check if there are any errors with it.
if (!mysqli_stmt_prepare($stmt, $sql)) {
// If there is an error send the user back to the record page.
header("Location: ../record.php?error=sqlerror");
exit();
}
else {
// If there is no error continue the script!
// bind the type of parameters we expect to pass into the statement, and bind the data from the user.
mysqli_stmt_bind_param($stmt, "ssi", $barcode, $weight, $userId);
// execute the prepared statement and send it to the database!
// data is registered to Db at this stage
mysqli_stmt_execute($stmt);
// send back with success
header("Location: ../record.php?record=success");
exit();
}
}
Add session_start() to the top and all worked.
Related
For some reason my last two variables will not input into the database. I am referring to $verifyKey and $keyExpire. Here is my code with comments. I am adding the entire page to make sure I don't have the wrong character somewhere it isn't supposed to be. Effectively this is a registration page that inserts the information into the database and gives a verification key for email verification later.
I have the fields matched up with the code in the database and they are set to longtext and text. I don't want to insert directly as I am trying to get this method to work with all 5 variables.
<?php
// This is not seen by the end user so this file is placed in the unseen folder
// Check if the user used the sign up button
if (isset($_POST['signup-submit'])) {
// uses the database handler
require 'dbh.php';
$username=$_POST['uid'];
$email=$_POST['mail'];
$password=$_POST['pwd'];
$passwordcnfrm=$_POST['pwd-cnfrm'];
$verifyKey=md5(time().$username);
$keyExpire=date("U")+ 86400;
// Checks to see if any field are empty
if(empty($username)||empty($email)||empty($password)||empty($passwordcnfrm)) {
// This header returns the username and/or email address so the user doesn't have to retype it
header("Location:../signup.php?error=emptyfields&uid=".$username."&mail=".$email);
exit();
}
// Checks if both the user and email are invalid
else if (!filter_var($email, FILTER_VALIDATE_EMAIL)&&!preg_match("/^[a-zA-Z0-9]*$/",$username)) {
header("Location:../signup.php?error=invalidmailuid");
exit();
}
// Checks if the email is valid
else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
header("Location:../signup.php?error=invalidmail&uid=".$username);
exit();
}
// Checks if the username is valid.
else if (!preg_match("/^[a-zA-Z0-9]*$/",$username)) {
header("Location:../signup.php?error=invaliduid&mail=".$email);
exit();
}
// Checks to see if the password and confirm password match
else if ($password !== $passwordcnfrm){
header("Location:../signup.php?error=passwordcheck&uid=".$username."&mail=".$email);
exit();
}
// Checks to see if the username is already in use or password is invalid
else {
$sql = "SELECT uidUsers FROM users WHERE uidUsers=?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt,$sql)) {
header("Location:../signup.php?error=sqlerror");
exit();
}
else {
mysqli_stmt_bind_param($stmt,"s",$username);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
$resultCheck = mysqli_stmt_num_rows();
if ($resultCheck < 0){
header("Location:../signup.php?error=usertaken&mail=".$email);
exit();
}
else {
//Inserts into database
$sql = "INSERT INTO users (uidUsers,emailUsers,pwdUsers,verify,expires) VALUES (?,?,?,?,?);";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt,$sql)) {
header("Location:../signup.php?error=sqlerror");
exit();
}
else {
$hashedPwd =password_hash($password,PASSWORD_DEFAULT);
mysqli_stmt_bind_param($stmt,"sssss",$username,$email,$hashedPwd,$verifyKey,$keyExpire);
mysqli_stmt_execute($stmt);
header("Location:../signup.php?signup=success");
}
}
}
}
//Closes session to db
mysqli_stmt_close($stmt);
mysqli_close($conn);
}
else {
header("Location:../signup.php");
}
In description of mysqli_stmt::bind_param there is this criptic note:
If data size of a variable exceeds max. allowed packet size
(max_allowed_packet), you have to specify b in types and use
mysqli_stmt_send_long_data() to send the data in packets.
http://php.net/manual/en/mysqli-stmt.bind-param.php
Practically it means that for every longtext (and blob) field you have to additionally call mysqli_stmt_send_long_data after mysqli_stmt_bind_param. Otherwise you have this strange behavious when everything works ok, but fields are not set.
The goal is to create profile settings page, where users can change their email address, but before updating ask them to enter their password.
So, I need to fetch password from database and compare it to password entered by user, and if they match update email address.
But, when I try to implement logic, I get a blank page. Code work till query. It stop working when $passwordCheck = true and $resultCheck = 0 (see edited below).
Edited (2019.01.09): redirects work till header('Location: ../edituser.php?success=emailupdate'). When enter new email, correct password and click submit button, it shows changeemail.php (my action script) page instead of redirect to edituser.php with success messsage. I assume that something get broken and script stuck. Also, added complete script.
Edited (2019.01.10): my question is: how to implement password confirmation before updating data using PHP. Above description shows how I tried to implement it. I'm looking for information about solution, different approaches to this problem or some help with my code. Sorry if I not clarify my question detailed enough. I also add profile settings picture below.
Picture 1. Profile settings page
changeemail.php script:
// Check for submit
if (isset($_POST['submit'])) {
// Get form data
$update_id = $_POST['update_id'];
$email = test_input($_POST['email']);
$confirm_password = test_input($_POST['confirm_password']);
// Store post id in session
session_start();
$_SESSION['update_id'] = $update_id;
// Check for empty field
if (empty($email)) {
header('Location: ../edituser.php?error=emptyemail');
exit();
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { // Check email
header('Location: ../edituser.php?error=invalidemail');
exit();
} else if (empty($confirm_password)) {
header('Location: ../edituser.php?error=emptyconfirmpassword');
exit();
} else {
// Check if email already exist
$query = "SELECT email, password FROM users WHERE email = ?";
// Create prepared statement
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $query)) {
header('Location: ../edituser.php?error=sqlerror');
exit();
} else {
mysqli_stmt_bind_param($stmt, 's', $email);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);
mysqli_stmt_bind_result($stmt, $email, $password);
$resultCheck = mysqli_stmt_num_rows($stmt);
while (mysqli_stmt_fetch($stmt)) {
// Check if passwords match
$passwordCheck = password_verify($confirm_password, $password);
if ($passwordCheck == false) {
header('Location: ../edituser.php?error=wrongconfirmpassword');
exit();
} else if ($passwordCheck == true && $resultCheck > 0) {
header('Location: ../edituser.php?error=emailtaken');
exit();
}
// Update email
$query = "UPDATE users SET email = ? WHERE id = ?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $query)) {
header('Location: ../edituser.php?error=sqlerror');
exit();
} else {
mysqli_stmt_bind_param($stmt, 'si', $email, $update_id);
mysqli_stmt_execute($stmt);
header('Location: ../edituser.php?success=emailupdate');
exit();
}
}
}
}
mysqli_stmt_close($stmt);
// Close connection
mysqli_close($conn);
} else {
header('Location: ../edituser.php');
exit();
}
As I said before - check your logic......
Sometimes that is best done in a 'reverse' manner - - - for instance, in this case, you say
When enter new email, correct password and click submit button, it shows changeemail.php (my action script) page instead of redirect to edituser.php with success messsage. I assume that something get broken and script stuck.
So, in other words....
EXPECTED RESULT: redirect to edituser.php
CURRENT RESULT: shows emailupdate (this is not clear in the question, though I believe that this is the case - you are redirecting to edituser.php?success=emailupdate. If this is not the case, clarify! My example below will presume this....)
So, let's follow the logic...... (remove all non-logic and/or redirection code to find why it is hitting where it is....)
First, let's look at why it isn't going where you want......
(EXPECTED RESULT: redirect to edituser.php)
Removing all code except what you expect, we get
// Check for submit
if (isset($_POST['submit'])) {
// DO ALL SORTS OF STUFF
} else {
// NEVER SELECT THIS IF THERE IS A 'SUBMIT' POSTED
header('Location: ../edituser.php');
exit();
}
However, to get to this page, you HAVE a 'submit', so the 'expected' line will NEVER be selected!
Now, let's look at what IS happening - and why......
// Check for submit
if (isset($_POST['submit'])) {
// Get form data
$update_id = $_POST['update_id'];
$email = test_input($_POST['email']);
$confirm_password = test_input($_POST['confirm_password']);
// Check for empty field
if (empty($email)) {
// WE HAVE EMAIL, SO THIS IS NOT HIT
} else if (!filter_var($email, FILTER_VALIDATE_EMAIL)) { // Check email
// EMAIL IS OK, SO NOT HIT
} else if (empty($confirm_password)) {
// PASSWORD IS OK, SO NOT HIT
} else {
// EMAIL FOUND SO WE ARE HERE
while (mysqli_stmt_fetch($stmt)) {
// Check if passwords match
$passwordCheck = password_verify($confirm_password, $password);
if ($passwordCheck == false) {
// PASSWORD IS OK, SO NO HIT
} else if ($passwordCheck == true && $resultCheck > 0) {
// OK, SO NO HIT
}
// Update email
$query = "UPDATE users SET email = ? WHERE id = ?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $query)) {
// NO FAILED SQL, SO NO HIT
} else {
// NO OTHER LOGIC, SO THIS _WILL_ BE A HIT........
// *****************************************
header('Location: ../edituser.php?success=emailupdate');
exit();
// *****************************************
}
}
}
}
}
Again, it is clear from your code that you will get the results you describe.
What I'm not sure of is really what you are expecting to do (so I can't really recommend code for you), though certainly the logic you are using is taking you where you are telling it to go - even though it is not what you would like to happen.....
You may need an additional check somewhere (to determine if you really need to update the email or just send them to the edituser page, etc.) - though you have to get the logic straight!
Hopefully this will show you a couple ways you can break down the code to get where you are wanting to go. I often START writing code with comments - then go back and fill in the logic with code. This both gives a simple way to follow along with the steps and gives well commented code for later debugging. I highly suggest you use such a system for your coding - certainly when starting out it is useful, but having well commented code will serve you well throughout your life.
To fix my issue I add another query:
$query = "SELECT password FROM users WHERE id = ?";
$stmt = mysqli_stmt_init($conn);
if (!mysqli_stmt_prepare($stmt, $query)) {
header('Location: ../index.php?error=sqlerror');
exit();
} else {
mysqli_stmt_bind_param($stmt, "i", $update_id);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
Old query won't find password for updated email, because it's not exist yet, and will close connection.
Just getting to grips with SQL and PHP and trying to build a simple user account system - with a forgotten password email link.
I have a script below that I am trying to use to update the password of a user. They receive an email with a link. The link looks like this: http://localhost:8887/email-password-reset.php?id=1.
I know this is unsafe and easily hackable! I am planning on using a randomly generated string of numbers, once I get this working!
I am trying to user the $_GET function to get the id. However I don't believe that the $_GET["id"] is getting passed to the $param_id variable.
I'm new to this so unsure how to rectify it!
How can I get this set the param_id to the $_GET Value?
At least that what I think the issue is from the error in the console (Undefined variable: param_id!) Thanks in advance!
<?php
//session_start();
require_once "config.php";
// Define variables and initialize with empty values
$new_password = $confirm_password = "";
$new_password_err = $confirm_password_err = "";
$param_id = '';
// Processing form data when form is submitted
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Validate new password
if(empty(trim($_POST["new_password"]))){
$new_password_err = "Please enter the new password.";
} elseif(strlen(trim($_POST["new_password"])) < 6){
$new_password_err = "Password must have atleast 6 characters.";
} else{
$new_password = trim($_POST["new_password"]);
}
// Validate confirm password
if(empty(trim($_POST["confirm_password"]))){
$confirm_password_err = "Please confirm the password.";
} else{
$confirm_password = trim($_POST["confirm_password"]);
if(empty($new_password_err) && ($new_password != $confirm_password)){
$confirm_password_err = "Password did not match.";
}
}
// Check input errors before updating the database
if(empty($new_password_err) && empty($confirm_password_err)){
// Prepare an update statement
$sql = "UPDATE users SET password = ? WHERE id = ?";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "si", $param_password, $param_id);
// Set parameters
$param_password = password_hash($new_password, PASSWORD_DEFAULT);
$param_id = (isset($_GET['id']) ? $_GET['id'] : '');
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Password updated successfully. Destroy the session, and redirect to login page
session_destroy();
header("location: login.php");
exit();
} else{
echo "Oops! Something went wrong. Please try again later.";
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// Close connection
mysqli_close($link);
}
?>
Cursory glance:
It's only going into your if if it's a POST type, by definition it'll be a GET type. You may need to remove/change that.
Secondly, you're building the query using $param_id before you assign $param_id to the GET variable.
If the only place, and it seems so, you're setting $param_id why not just declare it in the first line where you declare it as ''?
They receive an email with a link. The link looks like this: http://localhost:8887/email-password-reset.php?id=1
I assume if user click the link there will be a "new password" form. Then the form post the data to some url that contain the sciprt you use. To use $_GET['id'] you need make sure the url on the form ( maybe looks like action="http://localhost:8887/process.php") have GET parameter. So it's gonna looks like action="http://localhost:8887/process.php?id=1"
And the error Undefined variable: param_id! is because you use param_id before declare it. So, it's suppose looks like:
if($stmt = mysqli_prepare($link, $sql)){
// Set parameters
$param_password = password_hash($new_password, PASSWORD_DEFAULT);
$param_id = (isset($_GET['id']) ? $_GET['id'] : '');
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "si", $param_password, $param_id);
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
// Password updated successfully. Destroy the session, and redirect to login page
session_destroy();
header("location: login.php");
exit();
} else{
echo "Oops! Something went wrong. Please try again later.";
}
I have a table in which I need to edit/delete rows off a sql db using php. The problem (tale as old as time) is that neither delete/edit functions work correctly. I get no error messages, so I've been spending hours combing through the code and googling and searching through other similar questions on here and nothing that really addresses my specific problem.
I'm probably missing a quotation mark or something stupid like that, but some pointers would be really appreciated.
here is my editing code:
//if the 'id' variable is set in the URL, we know that we need to edit a record
if (isset($_GET['GroomingID']))
{
//if the form's submit button is clicked, we need to process the form
if (isset($_POST['submit']))
{
//make sure the 'id' in the URL is valid
if (is_numeric($_POST['GroomingID']))
{
//get variables from the URL/form
$GroomingID = $_POST['GroomingID'];
$firstName = htmlentities($_POST['FirstName'], ENT_QUOTES);
$lastName = htmlentities($_POST['LastName'], ENT_QUOTES);
//check that firstname and lastname are both not empty
if ($firstName == '' || $lastName == '')
{
//if they are empty, show an error message and display the form
$error = 'ERROR: Please fill in all required fields';
renderForm($firstName, $lastName, $error, $GroomingID);
}
else
{
//if everything is fine, update the record
if($stmt = $link->prepare("UPDATE grooming SET FirstName = ?, LastName = ? WHERE GroomingID=?"))
{
$stmt->bind_param("ssi", $firstName, $lastName, $GroomingID);
$stmt->execute();
$stmt->close();
}
//show an error message if the query encounters an error
else
{
echo "Error: could not preapre sql statement.";
}
//redirect the user once the form is updated
header("Location: PS_Manage_Appnts.php");
exit();
}
}
//if the 'id' variable isn't valid, show error message
else
{
echo "Error";
}
}
//if the form hasn't been submitted yet, get the info from the database and show the form
else
{
//make sure the 'id' value is valid
if (is_numeric($_GET['GroomingID']) && $_GET['GroomingID'] > 0)
{
//get 'id' from URL
$id = $_GET['GroomingID'];
//get the record from the database
if($stmt = $link->prepare("SELECT * FROM grooming WHERE GroomingID=?"))
{
$stmt->bind_param("i", $GroomingID);
$stmt->execute();
$stmt->bind_result($GroomingID, $firstName, $lastName);
$stmt->fetch();
//show the form
renderForm($firstName, $lastName, NULL, $GroomingID);
$stmt->close();
}
//show an error if the query has an error
else
{
echo "Error: could not prepare SQL statement.";
}
}
//if the 'id' value is not valid, redirect the user back to the PS_Manage_Appnts.php page
else {
header("location:PS_Manage_Appnts.php");
exit();
}
}
}
My delete code (separate from editing code):
<?php
//connect to the database
include ("newDBconn.php");
//confirm that the 'id'(in this case, 'GroomingID') variable has been set
if (isset($_GET['GroomingID']) && is_numeric($_GET['GroomingID']))
{
//get the 'id' variable from the URL
$GroomingID = $_GET['GroomingID'];
//delete record from the database
if ($stmt = $link->prepare("DELETE FROM grooming WHERE GroomingID = '?' LIMIT 1"))
{
$stmt->bind_param("i", $GroomingID);
$stmt->execute();
$stmt->close();
}
else
{
echo "ERROR: could not prepare sql statement.";
}
$link->close();
// redirect user after delete is successful
header ("location:PS_Manage_Appnts.php");
exit();
}
else
//if the 'id' variable isn't set, redirect the user
{
header("location:PS_Manage_Appnts.php");
exit();
}
?>
And lastly, the code for my db connection in a separate php file:
<?php
//connect to db
$link = mysqli_connect('localhost', 'root', 'pwdpwd', 'pet_shop');
//check connection
if (!$link) {
printf("Connection failed: %s\n", mysqli_connect_error());
exit();
}
?>
Notes: I'm aware of msql injection, but a) this is a test on my machine and b) I'd like to fix this problem first. Thank you for the help!
EDIT: I did run this through FireFox's Firebug and got no errors there either. I did, however, notice that when the 'delete' link on my table is clicked, firebug shows this:
http://i.imgur.com/oPqIfOk.png
There is no code linking the above underlined css file to my delete file (PS_delete_post.php) so I have no idea why it's trying to grab the css file. PS_delete_post.php isn't supposed to have any css linked to it to begin with.
EDIT2: I've changed the $firstName/$lastName variables to all lowercase as per Neo's suggestion. Now when 'edit' is clicked, the user is (correctly) directed to an empty form to input values, but hitting submit adds a new row instead of editing an existing row. 'Delete' still does not work.
Are you sending GroomingID from Post and Get?
In the Update File you retrieve the ID with this $GroomingID = $_POST['GroomingID']; But I am not sure if you sent it from Post or only Get.
I´m currently creating a login script in PHP. When a user tries to login <5 times in a short period of time the account get´s temporary locked and the user get´s an email in order to reactivate the account instantly. This is all working fine, the user fails to login, the database is updated and the email is sent. Then when I try to do this very same thing a second time with the second or third email, the database simply doesn't update. The only way to get it to work for the next email is to remove all values created from the first email in the database.
Here is the relevant code for the login php file.
<?php
include_once 'db_connect.php';
include_once 'functions.php';
...
} elseif (login($email, $password, $mysqli) == 2)
$theid = getId($email, $mysqli); /// this is a function that get´s id based on email located in functions.php
if ($stmt = $mysqli->prepare("SELECT emailSent FROM login_attempts WHERE user_id = ? LIMIT 1"))
{
$stmt->bind_param('i', $theid);
$stmt->execute();
$stmt->bind_result($skickat);
$stmt->fetch();
$stmt->close();
if ($skickat == '0') /// email sent
{
$thehash = md5( rand(0,10000) ); /// Just a random md5 hash for reactivation
$emailsent = 1;
if ($insert_stmt = $mysqli->prepare("UPDATE `secure_login`.`login_attempts` SET `ResetHash` = ?, `emailSent` = ? WHERE `login_attempts`.`user_id` = ?")) {
$insert_stmt->bind_param('sss', $thehash, $emailsent, $theid);
if (! $insert_stmt->execute()) {
header('Location: ../error.php?err=Registration failure: INSERT');
exit();
}
}
else {
header('Location: ../error.php?err=Registration failure: INSERT');
exit();
}
else /// alread sent, we already sent email. Show error that decribe email is sent and it´s locked
{
$_SESSION['lgnerror']= '<p class="error">Error 2</p>';
header('Location: ../login.php');
exit();
}
/// Email code starts from here
$_SESSION['lgnerror']= '<p class="error">Error 1</p>';
Here is the getId function located in functions.php
function getId($email, $mysqli)
{
if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE email = ? LIMIT 1"))
{
$stmt->bind_param('i', $email);
$stmt->execute();
$stmt->bind_result($resultat);
$stmt->fetch();
$stmt->close();
return $resultat;
}
else
{
// Could not create a prepared statement
header("Location: ../error.php?err=Database error: cannot prepare statement");
exit();
}
}
Why does the code only work for the first email and not when you try it a second time? I think the error lies somewhere in the code provided above, if needed just comment and I will provide more code.
The code on tests shows $_SESSION['lgnerror'] "error 2" on the 5th+ attempt when it schould show "error 1" on the 5th attemt. This indicates that $skickat != '0', even though the databse indicates that emailSent == '0' for the second emails id. I think the error probably is that that the user id is not updated so it just checks for the first email id which == '1'. I´m still a beginner at PHP and Mysqli so that might not be the error so please take a look and let me know what you think. What do you think is the error and how could I fix this so I could use this for more accounts than one, preferably with the security of prepared statements?
Im not sure but I think you got a mistake here.
In the function getId you do a bind_param of the email as an integer where it should be a string.
It should be like this:
function getId($email, $mysqli)
{
if ($stmt = $mysqli->prepare("SELECT id FROM members WHERE email = ? LIMIT 1"))
{
$stmt->bind_param('s', $email);
$stmt->execute();
$stmt->bind_result($resultat);
$stmt->fetch();
$stmt->close();
return $resultat;
}
else
{
// Could not create a prepared statement
header("Location: ../error.php?err=Database error: cannot prepare statement");
exit();
}
}