PDO count rows where username matches - php

I am trying to match a username in the database. If the username match it returns true otherwise it returns false.
At the moment it will always return false even when the username is correct.
Here is the class and call I'm using:
class register{
private $result;
public function __construct($post_data, PDO $dbh){
$this->post_data = array_map('trim', $post_data);
$this->dbh = $dbh;
}
public function checkUsername(){
$stmt = $this->dbh->prepare("COUNT(*) FROM oopforum_users WHERE username = ?");
$stmt->bindParam(1, $this->post_data['reg_username'], PDO::PARAM_STR);
$stmt->execute();
$this->result = $stmt->rowCount();
if($this->result == 0){
return false;
}else{
return true;
}
}
}
$register = new register($_POST, $dbh);
if($register->checkUsername()){
//continue
}else{
echo 'ERROR: That username is taken, please choose another one.';
}
Why is it returning false even though the username's do match?

You forgot the SELECT statement:
$stmt = $this->dbh->prepare("SELECT COUNT(*) FROM oopforum_users WHERE username = ?");
Apart from that your query will always return a row (exactly 1 row), but the contents of that row could contain a 0 for the row count, so you need to change your logic: Either select a real column instead of COUNT(*) and use $stmt->rowCount() or read the value of the count and check for that.

Related

PHP Delete function is deleting database row, but response is showing error?

I have created a PHP file called DB_Functions which contains my Delete method for removing a database row by User Id. Code:
//Delete User
public function deleteUser($id){
$stmt = $this->conn->prepare("DELETE FROM users WHERE user_id = ?");
$stmt->bind_param("s", $id);
$result = $stmt->execute();
$stmt->close();
}
I have then created another PHP file to act as an endpoint which calls this function after the Id is received as a POST parameter. Code:
require_once 'include/DB_Functions.php';
$db = new DB_Functions();
//json response array
$response = array();
if(isset($_POST['id'])){
//recieve GET parameters
$id = $_POST['id'];
$result = $db->deleteUser($id);
if($result){
$response["error"] = FALSE;
$response["message"] = "User deleted succesfully";
}else{
$response["error"] = TRUE;
$response["error_msg"] = "User did not delete";
}
echo json_encode($response);
}
When testing this using Advanced Rest Client and when using with an Andriod development I am working on, the row is deleted from the database but the parsed response in ARC is the error message and in the Android Logcat the same response message of "User did not delete" is shown?
Any help?
In your deleteUser function you are missing return statement. If you do not return anything then function will always return null.
So, In your case it's returning NULL and in further condition check it's going to else case.
public function deleteUser($id){
$stmt = $this->conn->prepare("DELETE FROM users WHERE user_id = ?");
$stmt->bind_param("s", $id);
$result = $stmt->execute();
$stmt->close();
return $result; // add this
}
Your function does not return any value, so when being compiled automatically returns a NULL value, which is why the error is always shown.
You need to add a return statement.
Return the result in the function...
public function deleteUser($id){
$stmt = $this->conn->prepare("DELETE FROM users WHERE user_id = ?");
$stmt->bind_param("s", $id);
$result = $stmt->execute();
$stmt->close();
return $result;
}

correct way to check if user is found in mysql table

The function should return the id of the found user or return false if not found.
Currently I am using bind result and fetch to check if a user is found in an mysql table:
public function getUserIDByName($UserName) {
$uid = "";
$i=0;
if($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")){
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
while($stmt->fetch()){
$i++;
}
$stmt->close();
}
if($i==0){
return false;
}else{
return $uid;
}
}
This works, but I assume that there is a proper way to do this without a counter in the fetch loop. I can not use get_result as mysqlnd is not available.
Simple use num_rows to check your query return result or not
function getUserIDByName($UserName) {
if ($stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?")) {
$stmt->bind_param("s", $UserName);
$stmt->execute();
$row_cnt = $stmt->num_rows;
if ($row_cnt == 1) {
$stmt->bind_result($uid);
while ($stmt->fetch()) {
return $uid;
}
} else {
return false;
}
}
}
Use this instead
public function getUserIDByName($UserName)
{
$uid = '';
$response = false;
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name=?");
$stmt->bind_param("s", $UserName);
$stmt->execute();
$stmt->bind_result($uid);
if ($stmt->fetch()) {
$response = $uid;
}
$stmt->close();
return $response;
}
EDIT: just realized you're using mysqli and not pdo. Ill leave this here if you want to use PDO in the feature I guess.
This is how I would do it. You could change rowcount() > 0 to rowcount() === 1 if you want to guarantee only 1 user is found.
public function getUserIDByName($UserName)
{
$stmt = $this->mysqlserver->prepare("SELECT uid FROM user WHERE name = :name");
// bind :name to the username
$stmt->bindParam(":name", $UserName);
// execute the query
$stmt->execute();
// check the rowcount
if ($stmt->rowcount() > 0) {
// fetch the results as a associative array
return $stmt->fetch(PDO::FETCH_ASSOC);
}
// return false because rowcount wasn't bigger than 0
return false;
}

PDO fetch() returning empty string

I am getting very frustrated. I have two functions which have similar "instructions" ie: return values from a users table in the database.
The second one works fine, however the first one is returning an empty value.
Here is the code:
public function ValidateUser($username, $password)
{
$stmt = "SELECT password FROM users WHERE username = :username LIMIT 1";
if(!($grabUser = $this->db->prepare($stmt)))
{
return null;
}
$grabUser->bindParam(":username", $username, PDO::PARAM_STR);
$grabUser->execute();
$data = $grabUser->fetch();
if(count($grabUser->fetchColumn()) <= 0)
{
return null;
}
echo $data['password'].'s';
if(!password_verify($password,$data['password']))
{
return null;
}
return $this->core->encrypt($data['password']);
}
I'm trying to display the $data['password'] on the page just to test whether it returns a value from the database, however it is simply returning empty, whereas the query is returning a column because it passes the
if(count($grabUser->fetchColumn()) <= 0)
{
return null;
}
condition.
The $username and $password variables are both set, so they are no problem.
Just in case you ask, this is the function that does work properly:
public function ValidateFacebookUser($email, $fid)
{
$stmt = "SELECT username, password FROM users WHERE email_address = :email AND connected_fb = '1' AND connected_fb_id = :fb LIMIT 1";
if(!($grabUser = $this->db->prepare($stmt)))
{
return null;
}
$grabUser->bindParam(":email", $email, PDO::PARAM_STR);
$grabUser->bindParam(":fb", $fid, PDO::PARAM_INT);
$grabUser->execute();
$data = $grabUser->fetch();
if(count($grabUser->fetchColumn()) <= 0)
{
return null;
}
return array($data['username'], $this->core->encrypt($data['password']));
}
It does turn the username and password for that case. Why does it not work in the first function?
Thanks.
No, you shouldn't mix up ->fetchColumn and ->fetch and with LIMIT 1.
What happens is that you already ->fetch() the first row. After that invocation of ->fetchColumn(), there's no more row to fetch.
public function ValidateUser($username, $password)
{
$stmt = "SELECT password FROM users WHERE username = :username LIMIT 1";
if(!($grabUser = $this->db->prepare($stmt))) {
return null;
}
$grabUser->bindParam(":username", $username, PDO::PARAM_STR);
$grabUser->execute();
$data = $grabUser->fetch(); // fetch once
// no need to add ->fetchColumn checking
$ret = null;
if(!empty($data['password']) && password_verify($password,$data['password'])) {
$ret = $this->core->encrypt($data['password']);
}
return $ret;
}
Look at the manual for fetchColumn(). You can see that this fetches the next result set. So if you've already called fetch(), there should be no next result set as per your code:
$data = $grabUser->fetch();
if(count($grabUser->fetchColumn()) <= 0)
{
return null;
}
This will always return null with a LIMIT 1 or single row result.

Count left attempts rows

I have this MYSQL Table :
id | action
A6bIMWP1rQ changedusername
A6bIMWP1rQ changedusername
Now how i make this php function to count if more then 5 times changedusername exsit, it will return false?
i have tryed:
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT action FROM userchange_attemps WHERE user_id = ?")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
// If there has been more than 5 failed logins
if($stmt->num_rows > 5) {
return true;
}else{
return false;
}
}
}
And how with php i determine how much left attemps upto 5 ?
Lets say now in my table theres 2 rows, and left 3 , how i return that value to the user ?
Thanks.
Use mysql COUNT
function checkIfOverFive($id,$mysqli) {
global $func; //The database connection
if ($stmt = $mysqli->prepare("SELECT COUNT(id) as count FROM userchange_attemps WHERE user_id = ? AND action = 'changedusername'")) {
$stmt->bind_param('i', $id);
// Execute the prepared query.
$stmt->execute();
$stmt->store_result();
$row = $stmt->fetch_assoc();
if($row['count'] > 5) {
//do something
} else {
//do something else
}
}
}
How about...
SELECT COUNT(action)
FROM userchange_attemps
WHERE action = 'changedusername' AND user_id= ?

How to successfully login on webpage using SHA1 + PDO + Prepared Statement?

I am fighting now like hours to figure out how to make possible to use SHA1 + PDO + Prepared Statement combination and still be able to log in to web page :) So my question is how to do so? Here is my code:
if (!empty($user) && !empty($password))
{
$password = $this->doHash($user, $password);
$stmt = $db_login->prepare("SELECT COUNT(*) FROM account WHERE username=:user AND sha_pass=:password");
$stmt->bindValue(':user', $user, PDO::PARAM_STR);
$stmt->bindValue(':password', $password, PDO::PARAM_STR);
$stmt->execute();
$results_login = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($results_login['COUNT(*)'] > 0)
{
$_SESSION['user_name'] = $results_login['username'];
$_SESSION['user_id'] = $results_login['id'];
return true;
}
else
{
return false;
}
}
else
{
return false;
}
My function doHash looks like this:
public function doHash($user, $password)
{
return sha1(strtoupper($user).":".strtoupper($password));
}
So my problems are: $results_login*** never processes with the SELECT COUNT(*) version, and with SELECT * version it processes sometimes, but not always. So how do I put it together to work as intended, result in true, and fill all the variables I need? Thank you.
Your SQL statement is only counting, it is not selecting the username and id, you would need to use this as your SQL statement, or something like it:
"SELECT * FROM account WHERE username=:user AND sha_pass=:password"
For your password binding, the following should work just fine. I would also use rowCount and only fetch, not fetchAll. Give this a try and see if it works.
$stmt->bindValue(':password', doHash($user,$password), PDO::PARAM_STR);
$stmt->execute();
if($stmt->rowCount()==1){
$results_login=$stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION['user_name'] = $results_login['username'];
$_SESSION['user_id'] = $results_login['id'];
return true;
}else{
return false;
}

Categories