I had problem running a query and counting the results with this code:
$this->db->get_where('user_tb', array('username' => $username, 'password' => $password) );
$count = $this->db->count_all_results();
And it always return 1 even if the username and password are wrong.
Then I changed my code to:
$sql = "SELECT * FROM user_tb WHERE username = ? AND password = ?";
$this->db->query($sql, array($username, $password));
$count = $this->db->count_all_results();
But the result is still the same.
Then my third and last try, I changed the code to:
$this->db->where('username', $username);
$this->db->where('password', $password);
$this->db->from('user_tb');
$count = $this->db->count_all_results();
Then it works. What are the differences between this three? Why is the last set of code works and the other two did not?
Its because $this->db->get_where(); and $this->db->query(); executed the query and returned the sql result and ended sql execution. After above two call when you are calling $this->db->count_all_results(); it is independent from above two calls. So it returns 1. and in
$this->db->where('username', $username);
$this->db->where('password', $password);
$this->db->from('user_tb');
$count = $this->db->count_all_results();
Execution is done with above three line query builder. So it is working fine.
Try this to see diffrence
$result = $this->db->get_where('user_tb', array('username' => $username,
'password' => $password) );
$count = $this->db->count_all_results();
print_r($result); // you will see it contains all data related to your query.
Without any query when you use $this->db->count_all_results(); which is equivalent to SELECT COUNT(*) AS numrows and will return 1. In your above two cases happening same.
In the 2nd line, you are using array , but in the 3rd line of your code you used single variable to compare column value thats why its working.
To use array in query use IN() operator.
Passing an array to a query using a WHERE clause
Try following code in your model
class Auth_login extends CI_Model
{
public function user_auth($username, $password)
{
$q = $this->db->where(['uname'=>$username, 'password'=>$password])
->get('table'); //your table name
if($q->num_rows())
{
return $q->row()->id; //primary key of returned row
}
else
{
return FALSE;
}
}
}
Add this code to the controller to authenticate user
$username = $this->input->post('user');
$password = $this->input->post('pwd');
$this->load->model('auth_login');
$login_id = $this->auth_login->user_auth($username, $password);
if($login_id)
{
$this->load->library('session');
$this->session->set_userdata('id',$login_id);
return redirect('user/dashboard');
}
else
{
$this->session->set_flashdata('feedback','password not match!');
}
return $this->load->view('index_login');
Hello try this code and it return's number of affected rows
$this->db->get_where('user_tb', array('username' => $username, 'password' => $password) );
$query = $this->db->get();
$rowcount = $query->num_rows();
and let me know it's working or not.
Related
I want to get information by user id, so lets add this to the model:
public function getById ($id)
{
$sql = 'SELECT * FROM users';
return ActualDbHander::run($sql);
}
later, I want to get only some fields:
public function getById ($id, $fields = '*')
{
$sql = 'SELECT '.$fields.' FROM users';
return ActualDbHander::run($sql);
}
another idea, lets add ordering:
public function getById ($id, $fields = '*', $orderBy = '')
{
$sql = 'SELECT '.$fields.' FROM users';
if ($orderBy != '')
{
$sql.= ' ORDER BY '.$orderBy;
}
return ActualDbHander::run($sql);
}
and I see this becaming messy and messy. What if I want to add JOIN-s? What if I want to add detailed WHERE-s? This is when "too generalic" methods born.
I completely agree with mch and Mjh comments, but, only in the case you actually want to have a "BD driver" (and build it yourself) I'd use different names for each query, very specific names, because you need to know exactly what a function will return to you.
So if I were you I would use names like getAllUsers, getUserById, getAllUsersOnlyPersonalData, getUserByIdOnlyPersonalData, getAllUsersOnlyContactData and so on (with fixed fields and filters for each method).
Note that in your examples you are not using at all the $id variable, so you are always receiving a list of users.
Regarding the method to make the queries, there are lots of ways to do it. Personally, I prefer MySQLi Object-Oriented prepared statements, because it's safe, easy and currently very extended, so I will use it just to ilustrate the examples.
Your functions would be something like this:
<?php
class DBDriver{
function openConnection(){
// If you don't always use same credentials, pass them by params
$servername = "localhost";
$username = "username";
$password = "password";
$database = "database";
// Create connection
$conn = new mysqli($servername, $username, $password, $database);
// Check connection
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// Return conection object
return $conn;
}
function closeConnection($conn){
$conn->close();
}
function getAllUsers (){ // We don't need ids here
$conn = $this->openConnection();
// Array of arrays to store the results
// You can use any other method you want to return them
$resultsArray = [];
$sqlQuery = "SELECT * FROM users";
// In this case it's not neccesary to use prepared statements because we aren't binding any param but we'll use it to unify the method
if ($stmt = $conn->prepare($sqlQuery)) {
// Execute query
$stmt->execute();
// Bind result variables (I don't know your actuall column names)
$stmt->bind_result($id, $name, $email, $phone, $birthdate);
// Fetch values
while ($stmt->fetch()) {
$resultsArray[] = [$id, $name, $email, $phone, $birthdate];
}
// Close statement
$stmt->close();
}
$this->closeConnection($conn);
// If no results, it returns an empty array
return $resultsArray;
}
function getUserByIdOnlyContactData ($userId){
$conn = $this->openConnection();
// Array to store the results (only one row in this case)
$resultsArray = [];
$sqlQuery = "SELECT name, email, phone FROM users WHERE id = ?";
if ($stmt = $conn->prepare($sqlQuery)) {
// Bind parameter $userId to "?" marker in $sqlQuery
$stmt->bind_param("i", $userId);
$stmt->execute();
$stmt->bind_result($name, $email, $phone);
// If id found
if ($stmt->fetch()) {
$resultsArray = [$name, $email, $phone];
}
// Close statement
$stmt->close();
}
$this->closeConnection($conn);
return $resultsArray;
}
function getAllUserOnlyBirthdayDataOrderByBirthday (){
$conn = $this->openConnection();
$resultsArray = [];
$sqlQuery = "SELECT id, name, birthdate FROM users ORDER BY birthdate";
if ($stmt = $conn->prepare($sqlQuery)) {
$stmt->execute();
$stmt->bind_result($id, $name, $birthdate);
while ($stmt->fetch()) {
$resultsArray[] = [$id, $name, $birthdate];
}
// Close statement
$stmt->close();
}
$this->closeConnection($conn);
return $resultsArray;
}
} // Class end
This way it's true you will have lots of functions depending on your requirements but as you can see it's extremely easy to add new ones or modify them (and you won't get mad with many different options in the same function).
Hope this helps you to organize your database driver!
please i have an issue with codeigniter. when i try to log here is the result:
Fatal error: Call to a member function num_rows() on boolean in D:\xampp\htdocs\procurementSys\application\models\login_model.php on line 19
Below tho code of the relative file:
<?php
class Login_model extends CI_Model {
//this function checks whether the username and the password is in the database or not
public function check_login($username, $password){
$this->db->select('username, password, status');
$array = array('username' => $username, 'password' => sha1($password),'status' => 'active');
$this->db->where($array);
$query = $this->db->get('user');
if($query->num_rows() == 1) // if the affected number of rows is one
{
return true;
}
else
{
return false;
}
}
//this function returns the status of the user to be used in authentication
public function user_login_data($username, $password){
$this->db->select('status');
$array = array('username' => $username, 'password' => sha1($password));
$this->db->where($array);
$query = $this->db->get('user');
if($query->num_rows() == 1) // if the affected number of rows is one
{
$row = $query->row();
return $row->status;
}
// else
// {
// return false;
// }
}
public function user_role($username){ // this function gets the user's role from the database
$this->db->select('role');
$this->db->where('username', $username);
$query = $this->db->get('user');
$row = $query->row(0);
return $row->role;
}
public function department($username){ // this function gets the user's department from the database
$this->db->select('department');
$this->db->where('username', $username);
$query = $this->db->get('user');
$row = $query->row(0); // returns the first row with an array of objects that is stored in the row variable
return $row->department;
}
public function get_user_id($username){ // this function gets the user's department from the database
$this->db->select('userID');
$this->db->where('username', $username);
$query = $this->db->get('user');
$row = $query->row(0); // returns the first row with an array of objects that is stored in the row variable
return $row->userID ;
}
public function fullname($username){
$this->db->select('firstName, secondName');
$this->db->where('username', $username);
$query = $this->db->get('user');
$row = $query->row(0);
return $row;
// foreach($query->result() as $row) // returns the query as an array of objects
// {
// $data[] = $row; // equates the array of objects to an array variable
// }
//
// return $data;
// }
}
}
?>
I kept searching for a solution and found this post (Call to a member function num_rows() on boolean) . It gave me an idea but no real help. thanks
I got this error with MySQL Strict Mode enabled. When I disable Strict Mode, error disappeared.
To check this mode is already enabled
SHOW VARIABLES LIKE 'sql_mode';
To make it disabled
SET GLOBAL sql_mode = 'NO_ENGINE_SUBSTITUTION';
Something like this for the count:
$this->db->select('id');
$this->db->from('table');
$this->db->where($your_conditions);
$num_results = $this->db->count_all_results();
**Try something like this **
//this function checks whether the username and the password is in the database or not
public function check_login($username, $password){
$this->db->select('username, password, status');
$array = array('username' => $username, 'password' => sha1($password),'status' => 'active');
$this->db->where($array);
$query = $this->db->get('user');
$result = $query->result();
if($result->num_rows() == 1) // if the affected number of rows is one
{
return true;
}
else
{
return false;
}
}
CODEIGNITER send boolean as result if there is not result
for example as per your method
public function check_login($username, $password){
$this->db->select('username, password, status');
$array = array('username' => $username, 'password' => sha1($password),'status' => 'active');
$this->db->where($array);
$query = $this->db->get('user');
if($query->num_rows() == 1) // if the affected number of rows is one
{
return true;
}
else
{
return false;
}
If there is no data in table it send False while we are expecting some object on which we can work so before calling $query->num_rows() check if it is an object or not so code can be like :
$query = $this->db->get('user');
if(is_object($query)){
if($query->num_rows() == 1) // if the affected number of rows is one
{
return true;
}
}else{
return false;
}
You can write like that. It will work smoothly.
if($query !== FALSE && $query->num_rows() == 1) // if the affected number of rows is one
{
return true;
}
else
{
return false;
}
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.
I'm currently making a validation process to check the old password of the user but problem is I can't get it why my query returns zero rows where expected it to have 1 row. 1 more thing is that even I don't convert my password text into md5 the hashed password still get the correct answer and I don't know why it happens. here's my code so far:
public function validate_oldpassword($username,$password)
{
$this->db->select('user_salt');
$query = $this->db->get_where('login',array('username' => $username));
if ($query->num_rows() == 1)
{
foreach ($query->result() as $row)
{
$password2 = hash("sha256",$password.$row->user_salt);
$this->db->flush_cache();
$query = $this->db->get_where('login', array('username' => $username, 'password' => $password2));
//return $this->db->last_query();
return $query->num_rows();
if($query->num_rows()==1){
return "YEHEY";
}else{
return "NO";
}
}
}
}
I also checked the query and it returns the correct query which is:
SELECT * FROM (`login`) WHERE `username` = 'kahel' AND `password` = 'f91d20d381426ea56e57da9ab23d0c568b8f934c3ff313e1bbf6c28a4fee758a'
My password is test salt is XgvT7F~(CYr#*0E1^UI#xkqJ5GcAO8BHsotZpf+WQ!4&ja2y%NdelLmhPSnRw9)zDK63VMuib and stored password is f91d20d381426ea56e57da9ab23d0c568b8f934c3ff313e1bbf6c28a4fee758a
what bothers me the most is that in my login page function everything works just fine. Here's my login code function:
public function get_login_credentials($username,$password)
{
$this->db->select('user_salt');
$query = $this->db->get_where('login',array('username' => $username));
if ($query->num_rows() == 1)
{
foreach ($query->result() as $row)
{
$password = hash("sha256",md5($password).$row->user_salt);
$query = $this->db->get_where('login', array('username' => $username, 'password' => $password));
return $query->num_rows();
}
}
}
I can't really figure it out why it returns zero rows.
In the login function you are setting:
$password = hash("sha256",md5($password).$row->user_salt);
and in validate_oldpassword you are setting:
$password2 = hash("sha256",$password.$row->user_salt);
you aren't doing the md5 hash on it
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.