I'm building a login class with PHP, but the variables used are empty when I pass them to the class method even though they shouldn't be.
I tried returning only the $username variable but it's still empty, though if I return it without using the class I can see that it gets assigned correctly.
I'm using multiple other classes with methods where the variables gets assigned correctly.
I don't know if i've stared myself blind and am missing something obvious or if there's something else causing this.
class Auth
{
private $mysqli;
public function __construct(mysqli $mysqli)
{
$this->mysqli = $mysqli;
}
public function login($username, $password) //These variables are empty, even when they shouldn't be
{
$return['error'] = true;
$uid = $this->getUserId(strtolower($username)); //Returns false because $username variable is empty
if (!$uid) {
$return['message'] = 'No such user.'; //Output
return $return;
}
$user = $this->getUser($uid);
if (!password_verify($password, $user['password'])) {
$return['message'] = 'Password incorrect';
return $return;
}
$return['error'] = false;
$return['message'] = 'Logged in';
return $return;
}
private function getUserId($username)
{
$stmt = $this->mysqli->prepare("SELECT id FROM users WHERE username = ?");
$stmt->bind_param('s', $username);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id);
if ($stmt->num_rows < 1) {
return false;
}
$stmt->fetch();
return $id;
}
private function getUser($uid)
{
$stmt = $this->mysqli->prepare("SELECT username, password, email FROM users WHERE id = ?");
$stmt->bind_param('s', $uid);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($username, $password, $email);
if ($stmt->num_rows < 1) {
return false;
}
$stmt->fetch();
$return['uid'] = $uid;
$return['username'] = $username;
$return['password'] = $password;
$return['email'] = $email;
return $return;
}
}
A form assigns the variables sent.
<form method="POST" action="post.php">
<label>Username
<input style="display:block;width:250px;" type="text" name="username" required></label>
<label>Password
<input style="display:block;width:250px;" type="password" name="password"></label>
<button style="display:block;" class="default_btn">Log in</button>
</form>
if (isset($_POST['username'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$auth = new Auth($mysqli);
$auth->login($username, $password);
if ($auth->login()['error']) {
echo 'error:' . $auth->login()['message'];
} else {
echo 'success:' . $auth->login()['message'];
}
}
EDIT:
If I assign the variables in the class method the code works:
public function login($username = 'user', $password = 'pass')
But if I do this, it will not work:
$username = 'User';
$password = 'pass';
$auth = new Auth($mysqli);
$auth->login($username, $password);
Also, if I use the $_POST values outside of $auth->login() they are assigned so they are not empty when passing them to the class...
The problem seems to be that you don't store the result and instead call login again without values: if ($auth->login()['error']) {.
Try this:
<form method="POST" action="post.php">
<label>Username
<input style="display:block;width:250px;" type="text" name="username" required></label>
<label>Password
<input style="display:block;width:250px;" type="password" name="password"></label>
<button style="display:block;" class="default_btn">Log in</button>
</form>
if (isset($_POST['username'])) {
$username = $_POST['username'];
$password = $_POST['password'];
$auth = new Auth($mysqli);
$login_result = $auth->login($username, $password);
if ($login_result['error']) {
echo 'error:' . $login_result['message'];
} else {
echo 'success:' . $login_result['message'];
}
}
Related
encrypt the password in the database with the following code:
$pas = $_POST['password'];
$pass = password_hash($pas, PASSWORD_BCRYPT);
in the solucioncontroller.php I try to verify the encrypted password but it does not work
class solucionController {
include_once 'model/solucion.php';
public function Login()
{
$solucion = new solucion();
if (isset($_POST["login"]) && isset($_POST["password"]))
{
$login = htmlentities(addslashes($_POST["login"]));
$password = htmlentities(addslashes($_POST["password"]));
$solucion = $this->model->Logeo($login, $password);
$pass= $this->model->getpass();
if (password_verify($password, $pass)&&$solucion == 1)
{
setcookie('usuario', $login, time() + 3600);
session_start();
$_SESSION["Usuario"] = $login;
header("Location: view/header.php");
header("Location: view/solucion/solucion.php");
header("Location: view/Footer.php");
}
}
header('Location: index.php');
return;
}
}
in the model solucion.php I search for the user and the password entered in the login view
class solucion {
public $res;
public function Logeo($login, $pass)
{
try {
$sql = "SELECT * FROM logeo WHERE usuario = :login AND pass = :password";
$resultado = $this->pdo->prepare($sql);
$resultado->bindValue(":login", $login);
$resultado->bindValue(":password", $pass);
$resultado->execute();
$numero_registro = $resultado->rowCount();
if ($numero_registro != 0)
{
return 1;
}
$this->res = $resultado->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
die($e->getMessage());
}
}
}
public function getpass(){
return $this->res['pass'];
}
in the login view is the form where you enter the username and password
<?php
if(isset($_COOKIE['usuario'])){
require 'view/solucion/solucion.php';
}
else{
?>
<a class="btn btn-success pull-right" href="?c=solucion&a=Invitado">Invitado</a>
<h1>Introduce tus datos</h1>
<form action="?c=solucion&a=Login" method="post">
<div class="container">
<label for="login"><b>Username</b></label>
<input type="text" placeholder="Ingrese usuario" name="login" required>
<label for="password"><b>Password</b></label>
<input type="password" placeholder="Ingrese Contraseña" name="password" required>
<button type="submit">Login</button>
</div>
</form>
<?php }?>
when entering the username and password, the data is deleted and I remain in the login view
You should fetch data using usuario only not using usuario and pass from database. Because password saved in database is hashed and can't be compared with simple text password entered by user. Change the model code as below:
class solucion {
public $res;
public function Logeo($login, $pass) {
try {
$sql = "SELECT * FROM logeo WHERE usuario = :login";
$resultado = $this->pdo->prepare($sql);
$resultado->bindValue(":login", $login);
$resultado->execute();
$numero_registro = $resultado->rowCount();
if ($numero_registro != 0) {
return 1;
}
$this->res = $resultado->fetch(PDO::FETCH_ASSOC);
} catch (Exception $e) {
die($e->getMessage());
}
}
}
public function getpass() {
return $this->res['pass'];
}
Also need to get password from request as:
$password = $_POST["password"];
instead of
$password = htmlentities(addslashes($_POST["password"]));
I am creating a login system with OOP PHP.
The problem is when executing the if...else statement where I check if the email is correct and the password of respective email is incorrect. If so, I display the error Password is incorrect.
However, the if...else statement is not working as expected. It returns no result i.e. NULL.
login.php
<?php
include('conn.php');
class Login extends Connection {
private $dbEmail;
private $dbPassword;
private $query;
public $emError;
public $paError;
public function loginFormHandler($email, $password) {
$this->query = $this->DB_CONN->prepare("SELECT `email`, `password` FROM `users` WHERE `email` = :email AND `password` = :password");
$this->query->bindParam(':email', $email);
$this->query->bindParam(':password', $password);
$this->query->execute();
while($row = $this->query->fetch(PDO::FETCH_ASSOC)) {
$this->dbEmail = $row['email'];
$this->dbPassword = $row['password'];
}
if ($this->dbEmail === $email && $this->dbPassword !== $password) {
$this->paError = 'Password Error';
}
}
public function errors() {
return array($this->emError, $this->paError);
}
}
And here's index.php
<?php
include('class/login.php');
$err = [];
if(isset($_POST['email']) && isset($_POST['password'])) {
$email = $_POST['email'];
$password = $_POST['password'];
if(!empty($email) && !empty($password)) {
$user = new Login;
$user->loginFormHandler($email, $password);
var_dump($err = $user->errors());
}
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Login Form</title>
</head>
<body>
<div class="form">
<form action="/oop/index.php" method="POST" accept-charset="UTF-8">
<label for="email">Email: </label><br>
<input type="email" name="email" required><br>
<?php if($err) {echo $err[0];} ?><br>
<label for="password">Password: </label><br>
<input type="password" name="password" required><br>
<?php if($err) {echo $err[1];} ?><br>
<input type="submit" value="Login">
</form>
</div>
</body>
</html>
As you can see, I am sending errors in a array and displaying the respective error.
Help me fix this.
simply check if row exist or not if exist start the session.otherwise redirect back with error
you can check if row exist by fetchColumn()
your login function should be like this
public function loginFormHandler($email, $password) {
$this->query = $this->DB_CONN->prepare("SELECT `email`, `password` FROM `users` WHERE `email` = :email AND `password` = :password");
$this->query->bindParam(':email', $email);
$this->query->bindParam(':password', $password);
$res=$this->query->execute();
$num_rows = $res->fetchColumn();
if ($num_rows>0) {
$row = $this->query->fetch(PDO::FETCH_ASSOC);
echo "success";
//Do something
}
else{
echo 'email or password is not valid';
//or do something
}
}
If in your code you take the email and password in the database it is obvious that the password will never be wrong (if it is wrong it does not take anything from the db = NULL). Your code like this:
class Login extends Connection {
private $email;
private $password;
private $query;
public $emError;
public $paError;
private function selectLogin(){
$this->query = $this->DB_CONN->prepare("SELECT `email`, `password` FROM `users` WHERE `email` = :email AND `password` = :password LIMIT 1");
$this->query->bindParam(':email', $this -> email);
$this->query->bindParam(':password', $this -> password);
$this->query->execute();
return $this->query->fetch(PDO::FETCH_ASSOC);
}
public function loginFormHandler($email, $password){
$this -> email = $email;
$this -> password = $password;
$result = $this -> selectLogin();
if(is_null($result)){
$this->emError = $this -> email;
$this->paError = 'Email or Password error';
} else {
// do something
}
}
public function errors() {
return array($this->emError, $this->paError);
}
}
I'm attempting to redirect users to their profile, with their username in the header. However, the redirect does not display the username. The login page asks for email and password (username omitted). Can someone show me what I'm doing wrong?
In class.php:
public function register($uname,$email,$upass,$code)
{
try
{
$password = md5($upass);
$stmt = $this->conn->prepare("INSERT INTO tbl_users(userName,userEmail,userPass,tokenCode)
VALUES(:user_name, :user_mail,
:user_pass, :active_code)");
$stmt->bindparam(":user_name",$uname);
$stmt->bindparam(":user_mail",$email);
$stmt->bindparam(":user_pass",$password);
$stmt->bindparam(":active_code",$code);
$stmt->execute();
return $stmt;
}
catch(PDOException $ex)
{
echo $ex->getMessage();
}
}
public function login($email,$upass,$uname)
{
try
{
$stmt = $this->conn->prepare("SELECT * FROM tbl_users WHERE
userEmail=:email_id AND userName=:user_name");
$stmt->execute(array(":email_id"=>$email,":user_name"=>$uname));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if($userRow['userStatus']=="Y")
{
if($userRow['userPass']==md5($upass))
{
$_SESSION['userSession'] = $userRow['userID'];
$_SESSION['userName'] = $userRow['userName'];
return true;
The redirect code:
public function redirectchannel()
{
header("Location: index.php?id=$userName");
}
login page:
if(isset($_POST['btn-login']))
{
$email = trim($_POST['txtemail']);
$upass = trim($_POST['txtupass']);
if($user_login->login($email,$upass))
{
$user_login->redirectchannel();
}
}
<input type="email" class="reginput" placeholder="Email address" name="txtemail" required />
<input type="password" class="reginput" placeholder="Password" name="txtupass" required />
<button class="formbutton" type="submit" name="btn-login">Login</button>
And landing page:
$stmt = $user_home->runQuery("SELECT * FROM tbl_users WHERE userID=:uid");
$stmt->execute(array(":uid"=>$_SESSION['userSession']));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
Though I don't know why you put username in a query string, as you already have it in a session, but still:
public function redirectchannel()
{
// what is `$userName` here? It is NULL
header("Location: index.php?id=$userName");
}
So, if you still want to pass username as query parameter, I suppose you can do:
public function redirectchannel()
{
header("Location: index.php?id=" . $_SESSION['userName']);
exit; //always exit immediately after location headers.
}
If I'm understanding this correctly, you don't need to pass the user name value through the URL. You're already creating a session variable with the user name:
$_SESSION['userName']
You can use this same variable in any page using the same session. Simply create a variable like:
$username = $_SESSION['userName'];
Now you can call this variable at any time on the page like so:
User Name: <?php echo $username; ?>
Always get an error: (Call to a member function bind_param() on a non-object error) .
I think my script can't connect to the db. db has only 3 fields, id, email, password. please any help.
database.php
<?php
class Database {
public function __construct() {
$host = '127.0.0.1';
$user = 'root';
$pass = '';
$name = 'test';
#$this->mysqli = new mysqli($this->host, $this->user, $this->pass, $this->name);
}
}
?>
users.php
<?php
include "database.php";
class Users extends Database {
public function login($email, $password) {
if($stmt = $this->mysqli->prepare("SELECT email, password FROM users WHERE `email` = ? AND `password` = ? LIMIT 1")){
$stmt->bind_param('sssss', $email, $password);
$stmt->execute();
$stmt->bind_result($email, $password);
$stmt->store_result();
if($stmt->num_rows == 1) {
while($stmt->fetch()) {
$_SESSION['email'] == $email;
echo $email;
}
} else {
echo "ERROR";
}
$stmt->close();
$stmt->free_result();
} else {
echo"Something went wrong";
}
}
}
$users = new users();
Login.php
<?php
session_start();
include "php/classes/users.php";
if(isset($_POST['login'])) {
$email = $_POST['email'];
$password = $_POST['password'];
$users->login($email, $password);
}
?>
login form
<form action="" method="POST" name="login">
<input type="email" name="email" id="username" placeholder="Vendoseni E-mailin"/><br/>
<input type="password" name="password" id="pass" placeholder="Vendoseni Passwordin"/><br/>
<input type="submit" name='login' value="Kycuni" id="login_btn"/>
</form>
You need to provide that properties in your class:
class Database
{
protected $mysqli; // change visibility
private $host = '127.0.0.1';
private $user = 'root';
private $pass = '';
private $name = 'test'; // these guys
public function __construct()
{
$this->mysqli = new mysqli($this->host, $this->user, $this->pass, $this->name);
}
}
Then on that Users class:
class Users extends Database
{
public function login($email, $password)
{
if($stmt = $this->mysqli->prepare("SELECT email, password FROM users WHERE `email` = ? AND `password` = ? LIMIT 1")){
$stmt->bind_param('ss', $email, $password);
// ^^ only two placeholders! not ssss
$stmt->execute();
$stmt->bind_result($email, $password);
$stmt->store_result();
if($stmt->num_rows == 1) {
while($stmt->fetch()) {
$_SESSION['email'] == $email;
echo $email;
}
} else {
echo "ERROR";
}
$stmt->free_result(); // free the result first, then close
$stmt->close(); // not the other way around.
} else {
echo"Something went wrong";
}
}
}
$users = new Users(); // initialize that particular class.
I've got a login session, in my login class I have created a function which fetches the user information for me. For now I have limited this to the user_id for now as I want to save this into the database so I can easily tell which user posted what in my database.
I am trying to access this function from a different class, my Login class.
I've tried two ways to call on this function from what I could find online:
$user_id = Login::usersessioninfo();
and
$login = new Login(); $login->useressioninfo();
However when I call either of these two ways I get the following error:
Fatal error: Call to a member function prepare() on a non-object in E:\xampp\htdocs\iproject\classes\class.Login.php on line 101
I don't understand why the PDO function is now suddenly a non object :/
Any ideas as to what I am doing wrong? The prepared statement is fine I've tested this alone in its own class but I'm having difficultly passing this through to another class.
This is my database:
<?php
# We are storing the information in this config array that will be required to connect to the database.
$config = array(
'host' => 'localhost',
'username' => 'root',
'password' => '',
'dbname' => 'imanage'
);
#connecting to the database by supplying required parameters
$pdo = new PDO('mysql:host=' . $config['host'] . ';dbname=' . $config['dbname'], $config['username'], $config['password']);
#Setting the error mode of our db object, which is very important for debugging.
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
?>
in a class I connect to my database as so:
EDIT: ADDED FULL LOGIN CLASS *
<?php
// Authentication
require_once 'init.php';
class Login {
private $pdo; // This variable will only be accessible from inside this class
public function __construct($database)
{
$this->pdo = $database;
} // end constructor method
public function validatelogin() {
$_SESSION['formAttempt'] = true;
if (isset($_SESSION['error'])) {
unset($_SESSION['error']);
}
$_SESSION['error'] = array();
$required = array("username","password");
//Check required fields
foreach ($required as $requiredField) {
if (!isset($_POST[$requiredField]) || $_POST[$requiredField] == "") {
$_SESSION['error'][] = $requiredField . " is required.";
}
}
//final disposition
if (count($_SESSION['error']) > 0) {
die(header("Location: ../index.php"));
} else {
unset($_SESSION['formAttempt']);
}
}//end validate login
function logged_in() {
if($_SESSION['authorized'] == true) {
return true;
} else {
return false;
}
}
function login_required() {
if($this->logged_in()) {
return true;
} else {
header("location: ../index.php");
}
}
public function loginuser() {
$username = (isset($_POST['username'])) ? $_POST['username'] : '';
$password = (isset($_POST['password'])) ? $_POST['password'] : '';
$Blowfish_Pre = '$2a£05$';
$Blowfish_End = '$';
$hashed_pass = crypt($password, $Blowfish_Pre . $row['salt'] . $Blowfish_End);
//$salt = "boo";
//$pw = crypt($password, $salt);
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password LIMIT 1");
$stmt->bindParam(":username", $username, PDO::PARAM_STR);
$stmt->bindParam(":password", $hashed_pass, PDO::PARAM_STR);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$total = $stmt->rowCount();
if($total > 0){
session_regenerate_id(true);
$_SESSION['username'] = $username;
$row['name'] = $name;
$_SESSION['authorized'] = true;
header("location: ../users.php");
} else {
echo "Wrong password or username";
}
//old login script.
//if (!$row)
// {
// echo "Invaild username or password. Try again";
// } else {
// $_SESSION['authorized'] = true;
// $_SESSION['username'] = $username;
// header("Location: testloginrequired.php");
// }
}// end loginuser
public static function usersessioninfo() {
$username = $_SESSION['username'];
$stmt = $this->pdo->prepare("SELECT * FROM users WHERE username = :username");
$stmt->bindParam(":username", $username, PDO::PARAM_STR);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// i can put this foreach above .. change $row above to $esult and then use for $row for the foreach()
foreach($result as $row) {
$username = $row['username'];
$id = $row['id'];
}
}
//public function selectuser() {
//$username = "test";
//$password = "password";
// $stmt = $this->pdo->prepare("SELECT * FROM users WHERE username = :username AND password = :password LIMIT 1");
// $stmt->bindValue(":username", $username);
//$stmt->bindValue(":password", $password);
// $stmt->execute();
// $result = $stmt->fetchAll(PDO::FETCH_ASSOC);
// foreach($result as $row) {
// $username = $row['username'];
// $email = $row['email'];
// echo $username;
//echo $password;
//echo $email;
// }//end foreach
// } // end function
}// End login class
$login = new Login($pdo);
$login->logged_in();
$login->login_required();
if (isset($_POST['submitlogin'])) {
$login->loginuser();
}
* EDIT PROJECTS CLASS *
classes/class.Project.php
<?php
include ('init.php');
include('class.Login.php');
class Projects extends Login {
private $pdo; // This variable will only be accessible from inside this class
public function __construct($database)
{
$this->pdo = $database;
} // end constructor method
public function createproject() {
//$login = new Login($pdo)
$user_id = $this->usersessioninfo();
$project_name = isset($_POST['project_name']) ? $_POST['project_name'] : null;
$project_brief = isset($_POST['project_brief']) ? $_POST['project_brief'] : null;
$data = array($user_id, $project_name, $project_brief);
$stmta = $this->pdo->prepare("INSERT INTO projects (user_id, project_name, project_brief) VALUES (?, ?, ?)");
if (isset($_POST['submitproject'])) {
$stmta->execute($data);
echo 'Right thats the boring stuff out of the way, lets create some tasks.';
printf("%d Row inserted.\n", $stmta->rowCount());
header("refresh:5; url=../users.php");
} else {
echo "Sorry something we couldn't process your project, you're been redirected to the registration page shortly.";
header("refresh:5; url=../create.php");
}
} // end function
} // end projects class
$run = new Projects($pdo);
$run->createproject();
//$login = new Login($this->pdo);
?>
init.php
<?php
session_start();
require 'class.Database.php';
//$errors = array();
?>
createproject.php
<?php
include('classes/class.Login.php');
include('header.html');
$run = new Login($pdo);
?>
<div id="maincontentWrapper">
<div id="maincontent">
<div id="contentWrapper"></div><!--End registerWrapper -->
<article>
<p>Right lets create your project! Fill in a few details...</p>
</article>
<div id="loginform">
<div id="registerWrapper">
<form id="registerForm" name="registerForm" method="POST" action="classes/class.Projects.php">
<h1><span class="log-in">Create a new project</span></h1>
<p class="required"><span class="log-in">*Required Fields</span></p>
<div id="errorDiv"><?php
if (isset($_SESSION['error']) & isset($_SESSION['formAttempt'])) {
unset($_SESSION['formAttempt']);
print "Errors encountered<br/>\n";
foreach ($_SESSION['error'] as $error) {
print $error . "<br />\n";
} //end foreach
} //end if
?></div>
<p class="float">
<label for="password"><i class="icon-lock"></i>Project Name*</label>
<input type="text" id="project_name" name="project_name" placeholder="Project Name" class="showpassword">
<span class="errorFeedback errorSpan" id="nameError">Project name is required</span>
</p>
<p class="float">
<label for="login"><i class="icon-user"></i>Project brief*</label>
<textarea rows="10" class="showpassword" name="project_brief" placeholder="Insert a short brief about your project"></textarea>
<span class="errorFeedback errorSpan" id="usernameError">Username is required</span>
</p>
<p class="float">
<label for="password"><i class="icon-lock"></i>Project Start Date*</label>
<input type="text" id="project_start_date" name="project_start_date" placeholder="Project Start Date" class="showpassword">
<span class="errorFeedback errorSpan" id="passwordError">Password is required</span>
</p>
<p class="float">
<label for="password"><i class="icon-lock"></i>Project End Date (Estimate if you can)*</label>
<input type="text" id="project_end_date" name="project_end_date" placeholder="Project End Date" class="showpassword">
<span class="errorFeedback errorSpan" id="password2Error">Passwords dont mat</span>
</p>
<p class="clearfix">
<input type="submit" name="submitproject" value="Register"></form>
</p>
</div>
</div>
</div>
</div>
</div>
<?php
include("footer.html");
?>
From the information you've posted, I can't see you passing the $pdo object to the "Login" class.
Can you post the entire Login class?
EDIT:
I see you've posted the full "Login" class. Well as far as I can tell, you are not passing the $pdo object to the "Login" class here:
$user_id = Login::usersessioninfo();
If you actually do the following, I believe it will work:
$login = new Login($pdo);
$login->useressioninfo();
In Project.php it should be
$login = new Login($this->pdo);
instead of
$login = new Login($pdo);
Global $pdo is not accessible from within the class method.