Notice: Trying to get property 'num_rows' of non-object - php

I'm reworking a login form to PDO based with OOP in mind. And I am running into the error given above. So I have two files one is an login.php and one is an included file called functions.inc.php
The code for the login.php is as follows.
<?php
include_once("includes/functions.inc.php");
// get username and password from $_POST
if(!empty($_POST)){
$username = $_POST['email'];
$password = $_POST['password'];
// check if a user can login (function)
if(canilogin($username, $password)){
session_start();
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = true;
header('Location: index.php');
}
else{
$error = true;
// if no -> $error tonen
}
}
?><!DOCTYPE html>
<html lang="en">
<body class="login">
<div class="grid container_login">
<div class="login_grid">
<form class="form_login" action="" method="post">
<?php if( isset($error) ): ?>
<div class="form__error">
<p>
Sorry, we can't log you in with that email address and password. Can you try again?
</p>
</div>
<?php endif;?>
<div>
<label for="email">EMAIL</label><br/>
<input type="text" id="email" name="email" placeholder="Lucasdebelder#snapshot.be" required>
</div>
<div>
<label for="password">PASSWORD</label><br/>
<input type="password" id="password" name="password" placeholder="Atleast 8 characters" required>
</div>
<div>
<input type="submit" value="LOG IN" class="btn_login">
</div>
<p class="center_align">Or</p>
<br/>
<a class="center_align" href="register.php">Register here.</a>
</form>
</div>
</body>
</html>
And the functions.inc.php where the error is happening, to be precise it happens at if($result->num_rows != 1){.
Also the first few lines were the once that worked before but that is done with real escape string to secure against SQL inject but it's kinda a wacky way to do and I decided to try to rework it to PDO.
<?php
function canilogin( $username, $password){
/* THIS IS THE OLD WAY THAT WORKED/WORKS
$conn = new mysqli("localhost", "root", "root", "snapshot");
$query = "select * FROM users WHERE email='".$conn->real_escape_string($username). "'";
$result = $conn->query($query);
*/
$conn = new PDO('mysql:host=localhost; dbname=snapshot', 'root', 'root');
//$query = "select * FROM users WHERE email='".$conn->real_escape_string($username). "'";
$statement = $conn->prepare("select * from users where email = :username");
$statement->bindValue(':username', $username);
$statement->execute();
$result = $statement->execute();
if($result->num_rows != 1){
return false;
}
$user = $result->fetch_assoc();
if(password_verify($password, $user['password'])){
return true;
}
else{
return false;
}
}
?>

The reason you are having the issue is that $result is not correct. Once $statement->execute(); is executed it becomes a PDOStatement object.
First of all remove $result = $statement->execute(); and try
if($statement->rowCount() != 1){
return false;
}
$user = $statement->fetch();
if(password_verify($password, $user['password'])){
return true;
}
else{
return false;
}

Related

PHP - Fatal error: Uncaught Error: Call to undefined method PDO::statement()

Fatal error: Uncaught Error: Call to undefined method PDO::statement() in /Applications/MAMP/htdocs/Snapshot/includes/functions.inc.php:13 Stack trace: #0 /Applications/MAMP/htdocs/Snapshot/login.php(16): canilogin('test#test.be', 'azertyui') #1 {main} thrown in /Applications/MAMP/htdocs/Snapshot/includes/functions.inc.php on line 13
Anyone knows how I can aroudn this problem? This is a login form, I've created an register form which works and saves the given input into an DB, the pw is saved as hashed as folowing $hash = password_hash($password,PASSWORD_DEFAULT);
Now I'm trying to create a login which doesn't seem to work at all after submitting it throws the error above then. Anyone can see what I did wrong? I'm working with OOP in mind.
Login.php:
<?php
include_once("includes/functions.inc.php");
// get username and password from $_POST
if(!empty($_POST)){
$username = $_POST['email'];
$password = $_POST['password'];
// check if a user can login (function)
if(canilogin($username, $password)){
session_start();
$_SESSION['username'] = $username;
$_SESSION['loggedin'] = true;
// setcookie("login", $cookieval, time()+60*60*24*7); //1 week
header('Location: index.php');
}
else{
$error = true;
// if no -> $error tonen
}
}
?><!DOCTYPE html>
<html lang="en"
<body class="login">
<div class="grid container_login">
<div class="login_grid">
<form class="form_login" action="" method="post">
<?php if( isset($error) ): ?>
<div class="form__error">
<p>
Sorry, we can't log you in with that email address and password. Can you try again?
</p>
</div>
<?php endif;?>
<div>
<label for="email">EMAIL</label><br/>
<input type="text" id="email" name="email" placeholder="Lucasdebelder#snapshot.be">
</div>
<div>
<label for="password">PASSWORD</label><br/>
<input type="password" id="password" name="password" placeholder="Atleast 8 characters">
</div>
<div>
<input type="submit" value="LOG IN" class="btn_login">
</div>
</form>
</div>
</body>
</html>
An extra file I used in includes/functions.inc.php to save the functions.
<?php
function canilogin( $username, $password){
$conn = new PDO('mysql:host=localhost; dbname=snapshot', 'root', 'root');
$statement = $conn->prepare("select * from users where email = :username");
$statement->bindValue(':username', 'username');
$statement->execute();
$result = $conn->statement($statement);
if($result->num_rows != 1){
return false;
}
$user = $result->fetch_assoc();
if(password_verify($password, $user['password'])){
return true;
}
else{
return false;
}
}
?>
replace the line that contain this code
$result = $conn->statement($statement);
by
if($statement->execute()){
$user = $statement->fetch(PDO::FETCH_ASSOC);
// and continue with your code that test the password
} else {
return false;
}

Login form doesn't verify the password

I am working on a login form and the password doesn't get verified from some reason. The user supposed to log in into system with email and password. I am matching user based on the email with the data in database. Could you please look at it?
Customer table
HTML form in file index.php
<div id="test-popup" class="white-popup mfp-hide col-sm-4 col-sm-offset-4 col-xs-10 col-xs-offset-1 align-center">
<img src="images/logo-white.png" alt="" height="120px" width="120px" />
<h5 class="font-alt">Login to Your Account</h5>
<br/>
<form method="post" action="login.php" class="form">
<div class="mb-20 mb-md-10">
<input type="text" name="email" id="email" class="input-md form-control" placeholder="Email" required />
</div>
<div class="mb-20 mb-md-10">
<input type="password" name="password" id="password" class="input-md form-control" placeholder="Password" required />
</div>
<div class="mb-20 mb-md-10">
<input type="submit" name="login" class="login btn btn-mod btn-medium" id="btnLogIn" value="Login" />
</div>
</form>
</div>
File login.php
<?php
require_once 'connection_db.php';
$response = new stdClass;
if (empty($_POST['email']) || empty($_POST['password'])) {
$response->success = false;
$response->message = 'Email and password cannot be empty.';
} else {
$sql = 'SELECT * FROM `customer` WHERE `email` = ? ';
$email = $_POST['email'];
$password = $_POST['password'];
$password = password_hash($password, PASSWORD_DEFAULT);
// print_r($password, true);
try {
$stmt = $db->prepare($sql);
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result();
$array = $result->fetch_array(MYSQLI_ASSOC);
// print_r($array, true);
if (count($array)) {
$response->success = true;
$response->message = 'Login successful.';
session_start();
$_SESSION['email'] = $email;
$_SESSION['id'] = $id;
$_SESSION['current_page'] = $_SERVER['HTTP_REFERER'];
header("Location: ". $_SESSION['current_page']);
} else {
$response->success = false;
$response->message = 'Wrong username or password.';
header("Location: index.php#test-popup");
}
}
catch (Exception $e) {
$response->success = false;
$response->message = "Error.";
}
}
// unset($db);
?>
Here's a generic setup of how your login script should look:
if (isset($_POST['submit']))
{
$email = $_POST['email'];
$password = $_POST['password'];
if (!empty($email) && !empty($password))
{
$res = $dbh->prepare("SELECT * FROM `customer` WHERE `email` = ?");
$res->execute([$email]);
$row = $res->fetch(MYSQLI_ASSOC);
if ($res->rowCount() > 0)
{
if (password_verify($password, $row['password']))
{
$_SESSION['user_session'] = $row['uid'];
header('Location: loggedIn.php');
} else {
// echo incorrect pass
}
} else {
// echo no such user...
}
} else {
// echo something...
}
}
You should be using password_verify for your login script. You only use password_hash for registering to hash the password that has been submitted.

php using pdo simple login system issues

<?php
if(isset($_POST["submit"])){
require 'Config.php';
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$Name = $_POST['Name'];
$Password = $_POST['Password'];
$message ="";
$stmt = $conn->prepare("SELECT COUNT(*) FROM user WHERE Name='$Name' and Password='$Password'");
$stmt->execute();
$result = $stmt->fetchcolumn();
if($result > 0)
{
$_SESSION['Logged In'] = $Name;
$_SESSION['Logged In'] = $Password;
if(isset($_SESSION['Logged In']))
{
echo $result;
session_start();
header('Location: Main.php');
exit();
}
}
elseif($result == 0)
{
echo $result;
echo "Invalid Username or Password";
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
$conn = null;
}
?>
i need help with this simple login system if i comment out the header redirect the echo result shows i am only getting 1 result as expected when i put the redirect in the page just refreshes instead of going to the next page.
There are a few simple issues in this code
First you must start the session before you do anything with it. In fact its best to start it at the top of every script before doing anything else.
Also because you have echoed something to the browser before you have run the header, this will be a probelm. Headers have to be sent before any page data.
Also your code is liable to SQL Injection so use prepared and parameterised queries to avoid this.
You also appear to be storing a plain text password in the database. another big No No
PHP provides password_hash()
and password_verify() please use them.
And here are some good ideas about passwords
If you are using a PHP version prior to 5.5 there is a compatibility pack available here
<?php
session_start();
if(isset($_POST["submit"])){
require 'Config.php';
$conn = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
try {
$stmt = $conn->prepare("SELECT Password
FROM user
WHERE Name=:name");
$params = array(':name'=>$_POST['Name'])
$stmt->execute($params);
$hashedPassword = $stmt->fetchcolumn();
if(password_verify($_POST['Password'], $hashedPassword) ) {
$_SESSION['Logged In'] = $_POST['Name'];
// bad idea putting password in a session
//$_SESSION['Logged In'] = $Password;
// you just set this data so the if is unnecessary
//if(isset($_SESSION['Logged In'])) {
// cannot echo anything before doing a header()
// any way if the header works you wont see this data
// anyway as a new page will be being loaded
//echo $result;
header('Location: Main.php');
exit;
} else {
echo $result;
echo "Invalid Username or Password";
}
catch(PDOException $e) {
echo $e->getMessage();
}
$conn = null;
}
?>
As this now uses a hashed password, you will have to recreate your users and when tou do, use
$passwordToPutOnDatabase = password_hash($thepassword);
There are may issues with your code, you are storing passwords in plain text which is completely wrong, you should use password_hash() and password_verify()
I have made you a simple login/register script which will show you how to use the password_hash and password_verify()
simple_register.php
<?php
require 'db_config.php';
if(isset($_POST['register'])){
//validate email and password I'm not gonna do that for you
$password = $_POST['upass']; // when u done with validation
$email = $_POST['username'];
$hash = password_hash($password,PASSWORD_DEFAULT); //hash password
try {
$stmt = $conn->prepare("INSERT INTO users (username,password) VALUES ( ?,?)");
if($stmt->execute(array($email,$hash))){
echo "user registered";
}else{
echo "could not register"; // something wrong with your query check error log
}
} catch (Exception $e) {
error_log($e->getMessage());
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title>Simple PDO Registration</title>
</head>
<body>
<form method="POST" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
<p><input type="email" name="username" placeholder="Enter your email"></p>
<p><input type="password" name="upass" placeholder="Enter password"></p>
<button type="submit" name="register">Register</button>
</form>
</body>
</html>
login.php
<?php
ob_start();
session_start();
require 'db_config.php';
if (isset($_SESSION['loggedin'])) {
header("location:users/dashboard.php");
} else {
$loginMessage = "";
$msg_class = "";
if (isset($_POST['login'])) {
if (empty($_POST['email']) || empty($_POST['upass'])) {
$loginMessage = "Enter username and password";
$msg_class = "error";
} else {
$username = $_POST['email'];
$password = $_POST['upass'];
try {
$stmt = $conn->prepare("SELECT userID,username,password FROM users where username = ? ");
$stmt->execute([$username]);
$results = $stmt->fetchall(PDO::FETCH_ASSOC);
if (count($results) > 0) {
foreach ($results as $row):
if (password_verify($password, $row['UserPassword'])) {
$_SESSION['loggedin'] = $row['userID'];
$loginMessage = "Login Successfully! Redirecting...";
$msg_class = "success";
header("refresh:5; url=dashboard");
} else {
$loginMessage = "Password and username does not match";
$msg_class = "error";
}
endforeach;
} else {
$loginMessage = "Invalid username";
}
}
catch (PDOException $e) {
error_log($e);
}
}
}
}
?>
</head>
<body>
<div id="main">
<h1>User Login</h1>
<div class="row">
<div class="large-6 columns large-centered" id="box">
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>" method="post">
<label>Email</label>
<input type="text" name="email" class="input" >
<label>Password </label>
<input type="password" name="upass" class="input" id="password"/><br/>
<div class="large-6 columns pull-2">Forgot Password</div>
<button type="submit" class="button" name="login" disabled="true" id="long">Login</button>
<div class="<?php echo $msg_class;?>">
<?php
echo $loginMessage;
?>
</div>
</form>
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){
$('#password').keyup(function(e){
$('#long').prop('disabled', false);
});
});
</script>
</div>
db_config.php
<?php
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "samedicalspecialists";
try {
$conn= new PDO("mysql:host=$servername;dbname=$dbname",$username,$password);
$conn->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
error_log($e);
}
?>

Trying to convert login from mysqli to sqlsrv

I am currently trying to convert a php login I have that uses mysql (I know this is a bit dated) to using sqlsrv. This is just a learning task as I wanted to learn to migrate a site from mySQL to MSSQL.
<?php
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
//Start session
session_start();
//Array to store validation errors
$errmsg_arr = array();
//Validation error flag
$errflag = false;
//Connect to mysql server
$serverName = "localhost";
$connectionInfo = array( "Database"=>"dbname", "UID"=>"sa", "PWD"=>"123");
$conn = sqlsrv_connect( $serverName, $connectionInfo );
if( $conn === false ) {
die( print_r( sqlsrv_errors(), true));
}
//Function to sanitize values received from the form. Prevents SQL injection
function clean($str) {
$str = #trim($str);
if(get_magic_quotes_gpc()) {
$str = stripslashes($str);
}
return $str;
}
//Sanitize the POST values
$login = clean($_POST['username']);
$password = clean($_POST['password']);
//Input Validations
if($login == '') {
$errmsg_arr[] = 'Login ID missing';
$errflag = true;
}
if($password == '') {
$errmsg_arr[] = 'Password missing';
$errflag = true;
}
//If there are input validations, redirect back to the login form
if($errflag) {
$_SESSION['ERRMSG_ARR'] = $errmsg_arr;
session_write_close();
header("location: index.php");
exit();
}
//Create query
$qry="SELECT * FROM users WHERE Username='$login' AND Password='".md5($_POST['password'])."'";
$stmt = sqlsrv_query( $conn, $qry );
//Check whether the query was successful or not
if($stmt) {
$row_count = sqlsrv_num_rows( $stmt );
if($row_count == 1) {
//Login Successful
session_regenerate_id();
$member = sqlsrv_fetch_assoc($stmt);
$_SESSION['SESS_MEMBER_ID'] = $member['idUsers'];
$_SESSION['SESS_FIRST_NAME'] = $member['FirstName'];
$_SESSION['SESS_LAST_NAME'] = $member['LastName'];
session_write_close();
header("location: home.php");
exit();
}else {
while( $row = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
echo $row['FirstName'];
$row_count = sqlsrv_num_rows( $stmt );
echo $row_count;
echo $stmt;
}
//Login failed
//header("location: index.php");
exit();
}
}else {
die("Query failed");
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Asset Manager</title>
<link rel="stylesheet" href="assets/main.css">
<link rel="stylesheet" href="assets/login.css">
</head>
<header>
<img src="img/logo.png">
</header>
<ul>
</ul>
<div class="main-content">
<form class="form-login" method="post" action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>">
<div class="form-log-in-with-email">
<div class="form-white-background">
<div class="form-title-row">
<h1>Log in</h1>
</div>
<div class="form-row">
<label>
<span>Username</span>
<input type="text" name="username" id="username">
</label>
</div>
<div class="form-row">
<label>
<span>Password</span>
<input type="password" name="password" id="password">
</label>
</div>
<div class="form-row">
<button type="submit" name="Submit" value="Login">Log in</button>
</div>
</div>
</div>
</form>
</div>
</body>
</html>
The issue is it just keeps going to the last else. I have been doing some troubleshooting as you can see in the code. the issue I think is that the rowcount does not work. When I echo ut the row count I just get a Resource 5 showing.
Any ideas?
The fix is to change
if($stmt) {
$row_count = sqlsrv_num_rows( $stmt );
if($row_count == 1) {
to:
if($stmt) {
$rows = sqlsrv_has_rows( $stmt );
if($rows === true) {
If project is old and messy, you might consider to write wrapping functions, something like this:
function mysql_num_rows($result){
$rows = sqlsrv_num_rows($result);
// change $rows in the way you need
return $rows;
}
Update
If you have no mysql extension, mysql_num_rows() will not be available and there will be no problem to define this function.
If you can not remove mysql extension, make it my_mysql_num_rows() and replace "mysql_" with "my_mysql_".

Why doesn't it sets the $_SESSION?

My script doesn't saves the value into a $_SESSION, how is that possible?
Whenever my users login, i try to place their username into a session.
My only problem is when i use var_dump($_SESSION['user_name']); to debug and reveal the current value on the end page, i just keep receiving NULL.
Could someone help me out?
Here is my code:
<? php
include_once('../db/config.php');
session_start();
$error = '';
if (isset($_POST['submit'])) {
if (empty($_POST['isamp_username']) || empty($_POST['isamp_password'])) {
$error = "Username or Password is invalid!";
} else {
$isamp = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
$username = stripslashes($username);
$password = stripslashes($password);
$username = $isamp - > real_escape_string($username);
$password = $isamp - > real_escape_string($password);
$username = $_POST['isamp_username'];
$nopassword = $_POST['isamp_password'];
$password_hash = hash('whirlpool', $nopassword);
$password = strtoupper($password_hash); // <- Also for the Register!
$sql = "select * from users where password='$password' AND username='$username'";
$result = $isamp - > query($sql) or trigger_error($isamp - > error." [$sql]"); /* i have added the suggestion from MY Common Sence */
if ($result - > num_rows == 1) {
$_SESSION['user_name'] = $username;
header("Location: ../../index.php");
} else {
$error = "Username or Password is invalid!";
}
$isamp - > close();
}
} ?>
My HTML:
<?php
include('login.php');
?>
<h2>iSAMP</h2>
<hr/>
<form action="" method="post">
<label>Username :</label>
<input type="text" name="isamp_username" id="name" placeholder="Username"/><br /><br />
<label>Password :</label>
<input type="password" name="isamp_password" id="isamp_password" placeholder="*******"/><br/><br />
<input type="submit" value=" Login " name="submit"/><br />
<span><?php echo $error; ?></span>
</form>
In your first php script, move the session_start() above the include statement.
In your html file, add session_start(); above the include statement.

Categories