checking username against database pdo - php

The script works to add user data into the db however I want the check if the username is in use but keep running into this error
Fatal error: Call to a member function rowcount() on a non-object in /home/4507408/public_html/registeruser.php on line 78
I cant seem to manage to do it with PDO, any help would be great!
<?php
$form = $_POST;
$username = $form[ 'username' ];
$password = $form[ 'password' ];
$firstname = $form[ 'firstname' ];
$location = $form[ 'location' ];
$age = $form[ 'age' ];
$email = $form[ 'email' ];
$usercheck = $_POST['username'];
$check = "SELECT username FROM use WHERE username = '$usercheck'";
$query = $DBH->prepare( $check );
$query = $DBH->prepare($check);
$query->execute();
$data = $query->fetchALL();
$check2 = $check->rowcount();
//if the name exists it gives an error
if ($check2 != 0) {
die('Sorry, the username '.$_POST['username'].' is already in use.');
}
$sql = "INSERT INTO user ( username, password, firstname, location, age, email ) VALUES ( :username, :password, :firstname, :location, :age, :email )";
$query = $DBH->prepare( $sql );
?>

This line:
$check = "SELECT username FROM use WHERE username = '$usercheck'";
is wrong. use is a SQL reserved word. I assume you meant user. It's also a terrible idea to inject a value into the query string with simple variable substitution. The whole point of PDO is to use parametrized queries: http://us1.php.net/pdo.prepared-statements

Related

PDO PHP UPDATE don´t update Password if not included

I have an updating form to update the users information. Here, I have the password input. And I want to, if left blank, not update the password in the database but to leave the one already set up.
For this I have:
$user_password = inputCleaner($_POST['user_password']);
$user_password_repeat = inputCleaner($_POST['user_password_repeat']);
// IF filled, check if both match
if (!empty($user_password) && $user_password != $user_password_repeat) {
$errors .= "Passwords are not the same." . '<br>';
} elseif (!empty($user_password) && $user_password == $user_password_repeat) {
$user_password = hash('sha512', $user_password);
}
// IF NOT FILLED, leave NULL
elseif (empty($user_password)) {
$user_password = '';
}
If all is good, we run the script:
if(!$errors) {
$statement = $connection -> prepare("
UPDATE users SET
user_nickname = :user_nickname,
user_password = COALESCE(NULLIF(:user_password, ''),user_password)
user_pass
user_name = :user_name,
user_last_name = :user_last_name,
user_email = :user_email,
user_picture = :user_picture,
role = :role
WHERE
user_id = :user_id
");
$statement -> execute(array(
':user_nickname' => $user_nickname,
':user_password' => $user_password,
':user_name' => $user_name,
':user_last_name' => $user_last_name,
':user_email' => $user_email,
':user_picture' => $user_picture,
':role' => $role,
':user_id' => $user_id
));
Note my inputCleaner() function is a simple:
function inputCleaner($input) {
$input = trim($input);
$input = stripslashes($input);
$input = htmlspecialchars($input);
return $input;
}
With this, the password is not updated at all, it won´t change it.
Instead of converting '' to NULL and then using COALESCE(), you can simply compare :user_password to ''.
You also had some syntax errors: a missing comma after assigning to user_password and an extra line with user_pass after that.
$statement = $connection -> prepare("
UPDATE users SET
user_nickname = :user_nickname,
user_password = IF(:user_password = '',user_password, :user_password),
user_name = :user_name,
user_last_name = :user_last_name,
user_email = :user_email,
user_picture = :user_picture,
role = :role
WHERE
user_id = :user_id
");```

Secure form handling using stmt prepare

The prepare function is not recognizing members that already exist in the DB and as a result, always calls the function NewUser() when it is supposed to go through the else statement? I believe this is because when I ask it to verify the password, it encounters an error, but I have no idea what I am doing wrong?
function NewUser(){
global $dbh;
$fullname = trim($_POST['fullname']); //at a minimus clear whitespace.
$username = trim($_POST['username']);
$email = trim($_POST['email']);
$user_password = trim($_POST['password']);
$options = [
'cost' => 12, //higher = more lower= less. you want it to take around 0.4 seconds for security reasons!
];
$hashed_password = password_hash($user_password, PASSWORD_DEFAULT, $options); // hashed password for storage!
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password) VALUES('$fullname', '$username', '$email', '$hashed_password')");
$stmt->bindValue(1,$fullname,PDO::PARAM_STR);
$stmt->bindValue(2,$username,PDO::PARAM_STR);
$stmt->bindValue(3,$email,PDO::PARAM_STR);
$stmt->bindValue(4,$user_password,PDO::PARAM_STR);
if($stmt->execute()){
echo "<div class= container>","<div class = \" col-md-2 connout slideInTop\">"," <span class = \"username_text\">$username</span>, <br> welcome to <br> the <br> <span class = \"vibecourt_text\">VIBECOURT</span> family! <br><br> You may <br> now sign in <br> below","</div>","</div>";
}
}
function SignUp(){
global $dbh;
//checking the 'user' name which is from index.php, is it empty or have some text
if(!empty($_POST['username'])){
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE (username = ? AND password = ?)");
$stmt->bindValue(1, $_POST['username'],PDO::PARAM_STR);
$stmt->bindValue(2, $_POST['password'],PDO::PARAM_STR);
$stmt->execute();
$selected_row = $stmt->fetch(PDO::FETCH_ASSOC);
//check password agaisnt stored hash
if(!password_verify($password, $selected_row['password'])) {
NewUser();
}
else{
echo("<script>location.href = 'pages/home/home.php'</script>");
}
}
}
SignUp();
Updated Answer
In light of what transpired in comments... it appears the issue is further rooted far above where you are originally storing the hashed password into the database.
You say you are using a varchar(50), for a password_hash value. This is too short, and mysql is no doubt clipping the INSERT. This will result in hashes that can never be matched.
You should have a varchar(60) at the very minimum, but PHP.net states that this hash can grow over time, and using a varchar(255) is recommended.
In this bit:
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE (username = ? AND password = ?)");
$stmt->bindValue(1, $_POST['username'],PDO::PARAM_STR);
$stmt->bindValue(2, $_POST['password'],PDO::PARAM_STR);
You are trying to match the hashed value in the database, with a user inputted password (which is not hashed).
You should simply remove the AND password = ? and bindValue for it. That way it pulls a matching username entry from the db, and THEN does password_verify to determine if the user inputted password, matches:
$username = trim($_POST['username']);
$password = trim($_POST['password']);
$stmt = $dbh->prepare("SELECT * FROM USERS WHERE username = ?");
$stmt->bindValue(1, $username, PDO::PARAM_STR);
$stmt->execute();
$selected_row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!password_verify($password, $selected_row['password'])) {
NewUser();
}
Side note: Although I'm not sure you really WANT to make a new user if they simply typed in the wrong password??? Surely you would handle that differently. Telling them they entered a wrong password and should try again.
EDIT
Also in your NewUser function you have this:
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password)
VALUES('$fullname', '$username', '$email', '$hashed_password')");
It should be this:
$stmt = $dbh->prepare("INSERT INTO USERS(fullname, username, email, password)
VALUES(?, ?, ?, ?)");
// ...
$stmt->bindValue(4,$hashed_password,PDO::PARAM_STR);// <- use $hashed_password

Need help to insert many rows in my SaaS project using PDO

I'm trying to develop a SaaS project. I have to, when the new company register, it automatically registers all permission params and permission groups it's going to have. The code is working including a company, a user in that company within the permission group Admin and he has clients view permission.
Now I need to add the other permissions the same way, they have to be created and added to the admin group just created. I'm trying this, but it only adds the first param (clients_view) and not the second param (clients_edit)
<?php
require_once 'config.php';
$name = isset($_POST['name']) ? $_POST['name'] : null;
$cnpj = isset($_POST['cnpj']) ? $_POST['cnpj'] : null;
$username = isset($_POST['username']) ? $_POST['username'] : null;
$email = isset($_POST['email']) ? $_POST['email'] : null;
$password = isset($_POST['password']) ? $_POST['password'] : null;
if (empty($name) || empty($cnpj) || empty($username) || empty($email) || empty($password) ){
echo "Please fill all fields";
exit;
}
//Creates the new company
$PDO = db_connect();
$sql = "INSERT INTO companies (name, cnpj) VALUES(:name, :cnpj)";
$stmt = $PDO->prepare($sql);
$stmt->bindParam(':name', $name);
$stmt->bindParam(':cnpj', $cnpj);
$stmt->execute();
//creates permission param clients_view
$id_company = $PDO->lastInsertId();
$name = 'clients_view';
$sql2 = "INSERT INTO permission_params (id_company, name) VALUES (:id_company, :name)";
$stmt2 = $PDO->prepare($sql2);
$stmt2->bindParam(':id_company', $id_company);
$stmt2->bindParam(':name', $name);
$stmt2->execute();
//creates permission group Admin with param clients_view
$params = $PDO->lastInsertId();
$name = 'Admin';
$sql3 = "INSERT INTO permission_groups (id_company, name, params) VALUES (:id_company,:name, :params)";
$stmt3 = $PDO->prepare($sql3);
$stmt3->bindParam(':id_company', $id_company);
$stmt3->bindParam(':name', $name);
$stmt3->bindParam(':params', $params);
$stmt3->execute();
//create new user and adds to Admin group
$id_group = $PDO->lastInsertId();
$sql4 = "INSERT INTO users (username, email, password, id_group, id_company) "
. "VALUES (:username, :email, :password, :id_group, :id_company)";
$stmt4 = $PDO->prepare($sql4);
$stmt4->bindParam(':username', $username);
$stmt4->bindParam(':email', $email);
$stmt4->bindParam(':password',md5($password));
$stmt4->bindParam(':id_group', $id_group);
$stmt4->bindParam(':id_company', $id_company);
$stmt4->execute();
//creates permission clients_edit
// NOT WORKING
$name = 'clients_edit';
$sql5 = "INSERT INTO permission_params (name) VALUES (:name) WHERE id_company=:id_company";
$stmt5 = $PDO->prepare($sql5);
$stmt5->bindParam(':name', $name);
$stmt5->bindParam(':id_company', $id_company);
$stmt5->execute();
//Insert permission clients_view in group Admin
//NOT WORKING
$params = $PDO->lastInsertId();
$sql6 = "INSERT INTO permission_groups ( params) VALUES ( :params) WHERE name=:name AND id_company=:id_company";
$stmt6 = $PDO->prepare($sql6);
$stmt6->bindParam(':params', $params);
$stmt6->bindParam(':name', $name);
$stmt6->bindParam(':id_company', $id_company);
$stmt6->execute();
header('Location: index.php');
INSERT INTO permission_params (name) VALUES (:name) WHERE id_company=:id_company
That's wrong. You can't INSERT that again in that ID. You can INSERT new with new ID, or you can UPDATE that ID with new name OR you can create new table there insert ID from this table and on that way connect some other table with this table. If you know what I mean, maybe not the best explanation :D

How to generate token and create a url to send to email

I am trying to write a script for a student registration page, where a student enters his/her student id and if it exists then retrieve his/her email and generate a token and insert the token into the database and then send a registration url link with token and id to the student's email..how would i get that since i am a beginner in php and mysql.
where am i going wrong here?
<?php
error_reporting(1);
session_start();
include 'includes/connect.php';
include 'includes/tokengenerator.php';
if ($_POST["Submit"] == "Submit") {
$stu_id = $_POST['stu_id'];
$sql = "SELECT email FROM people WHERE stu_id = :stu_id";
$stmt = $pdo->prepare($sql);
$stmt->bindValue(':stu_id', $stu_id);
$stmt->execute();
$result = $stmt->fetch(PDO::FETCH_ASSOC);
if (!empty($result)) {
$email = $result['email'];
//echo $email;
//exit();
for ($i = 1; $i <= 2; $i++) {
$token = generateToken();
//echo $token;
$email = $result['email'];
$sql = "INSERT INTO students (token) VALUES ($token) WHERE email = :email";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
':token' => $token,
));
$result1 = $stmt->fetch(PDO::FETCH_ASSOC);
}
} else {
echo 'Please Contact principal for student ID';
}
}
?>
You are binding the wrong value in the query: :token vs :email.
You should actually have 2 placeholders and bind both values.
$sql = "INSERT INTO students (token) VALUES (:token) WHERE email = :email";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
':token' => $token,
':email' => $email
));
And as noted correctly by #Saty, you cannot have a WHERE clause on an INSERT statement:
$sql = "INSERT INTO students (token, email) VALUES (:token, :email)";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
':token' => $token,
':email' => $email
));
Or you might need an UPDATE statement instead of an INSERT:
$sql = "UPDATE students SET token = :token WHERE email = :email";
$stmt = $pdo->prepare($sql);
$stmt->execute(array(
':token' => $token,
':email' => $email
));

Warning: PDOStatement::execute(): SQLSTATE[HY093]: Invalid parameter number: parameter was not defined in C:\wamp\www\PDO.php on line 24

Today, I was trying my code and I got this error : parameter was not defined...
Please, help me:
<?php
$user = 'dbuser';
$pass = 'pwd';
$db = new PDO( 'mysql:host=localhost;
dbname=registration', $user, $pass );
$form = $_POST;
$firstname = $form[ 'firstname' ];
$lastname = $form[ 'lastname' ];
$username = $form[ 'username' ];
$email = $form[ 'email' ];
$password = $form[ 'password1' ];
$dateofbirth = $form[ 'dateofbirth' ];
$monthofbirth = $form[ 'monthofbirth' ];
$yearofbirth = $form[ 'yearofbirth' ];
$gender = $form[ 'gender' ];
$sql = "INSERT INTO members ( firstname, lastname, username, email,
password, dateofbirth, monthofbirth, yearofbirth, gender )
VALUES ( :firstname, :lastname, :username,
:email, :password1, :dateofbirth, :monthofbirth, :yearofbirth,
:gender )";
$query = $db->prepare( $sql );
$query->execute( array( ':firstname'=>$firstname, ':lastname'=> $lastname,
':username'=>$username, ':email'=>$email, ':password'=>$password,
':dateofbirth'=>$dateofbirth, ':monthofbirth'=>$monthofbirth,
':yearofbirth'=>$yearofbirth, ':gender'=>$gender ) );
$result = $query->execute( array( ':firstname'=>$firstname, ':lastname'=>$lastname,
':username'=>$username, ':email'=>$email, ':password'=>$password,
':dateofbirth'=>$dateofbirth, ':monthofbirth'=>$monthofbirth,
':yearofbirth'=>$yearofbirth, ':gender'=>$gender ) );
if ( $result ){
echo "<p>Thank you. You have been registered</p>";
} else {
echo "<p>Sorry, there has been a problem inserting your details. Please contact admin.</p>";
}
?>
In the query string you're passing to PDO::prepare you have this parameter:
:email, :password1
But the array you're passing to PDOStatement::execute doesn't have a :password1 key, it has a :password key instead. It's a simple typo: fix either one or the other.
It might be a good idea to sanitize the actual submitted data before storing it in the DB, though. Things like an email address are easily verified using something like:
if (!filter_var($email, FILTER_VALIDATE_EMAIL))
{
printf(
'%s is not a valid email address, please fill in correct values',
$email
);
//rebuild form, and return response to client
}
else
{
//carry on validating data, eventually insert it in the DB
}
It's also important not to forget to check the post params using isset, if you don't your code can, and will, generate a lot of notices

Categories