PHP PDO Update Statement not working - php

This is probably an easy thing for you geniuses, but I have tried all of the ways I know and can't get this UPDATE Statement to work. The problem is with the update statement or the execute binding. I want the statement to add 2 points to the user's points column.
<?php
$dbConnection = new PDO('mysql:dbname=App;host=localhost;charset=utf8', '*', '*');
$dbConnection->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbConnection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$points = 2;
$username = $_POST["username"];
$password = $_POST["password"];
$response = array();
$stmt->$dbConnection->prepare("UPDATE user SET points = points + ? WHERE username = ? AND password = ?");
$stmt->execute(array($points, $username, $password));
$hi = $dbConnection->prepare("SELECT username, password, points FROM user WHERE username = ? AND password = ?");
$hi->execute(array($username, $password));
$red = $hi->fetchAll(PDO::FETCH_ASSOC);
if (count($red) > 0){
$response["success"] = true;
foreach($red as $item) {
$response["username"] = $item["username"];
$response["password"] = $item["password"];
$asd = $item["points"];
$response["points"] = (string)$asd;
}
}else{
$response["success"] = false;
}
echo json_encode($response);
?>

You need to assign $stmt to the prepared statement from the connection
$stmt = $dbConnection->prepare("UPDATE user SET points = points + ? WHERE username = ? AND password = ?");

Related

Php MySql Select count with prepared statment return always 1

I'm using this method to get make a login Web Service:
function redeem() {
if (isset($_POST["user"]) && isset($_POST["pass"]) && isset($_POST["computer"])) {
$user = $_POST['user'];
$pass = $_POST['pass'];
$computer = $_POST['computer'];
$galNumb = "SELECT COUNT(*) FROM Useres WHERE username = ? AND password = ?";
$stmt = $this->db->prepare($galNumb);
$stmt->bind_param('ss', $user, $pass);
$gNumb = $stmt->execute();
$result = array(
"success" => "true",
);
$this->sendResponse(200, $gNumb);
return true;
}
$this->sendResponse(400, 'Invalid request');
return false;
}
The problem is that $gNumb always return 1 even when the sql table not contain the username and the password. Any idea what can be the problem?
You forgot to fetch results:
...
$stmt->bind_param('ss', $user, $pass);
if ($stmt->execute()) {
$stmt->bind_result($gNumb);
$stmt->fetch();
} else {
$gNumb = 0;
}
...

php login script not giving expected result, or any

i have a php login script which is accessed with a simple form:
<?php
session_start();
try{
$user = 'root';
$pass = null;
$pdo = new PDO('mysql:host=localhost; dbname=divebay;', $user, $pass);
if(isset($_SESSION['loggedin'])){
echo "1"; //already logged in
}
else{
$username = $_POST['username'];
$password = sha1($_POST['password']);
$ucheck = $pdo->prepare('SELECT * FROM user WHERE username = ?');
$ucheck->bindValue(1, $username);
$ucheck->execute();
if($ucheck->fetch(PDO::FETCH_OBJ)){
$stmt = $pdo->prepare('SELECT * FROM user WHERE username = ? AND password = ?');
$stmt->bindValue(1, $username);
$stmt->bindValue(2, $password);
if($stmt->fetch(PDO::FETCH_OBJ)){
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION['username'] = $row['username'];
$_SESSION['loggedin'] = 'YES';
$_SESSION['location'] = $row['location'];
echo "2"; //logged in
}
else{
echo "3"; //password incorrect
}
}
else{
echo "4"; //user does not exist
}
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
but when i attempt to run it using an account that i just created and have confirmed to exist within the database, i get no response from this script. i would expect it to echo 2 given that the login information is correct, but i get nothing
can anyone suggest what ive done wrong here?
It looks like you forgot to execute() the statement:
if($ucheck->fetch(PDO::FETCH_OBJ)){
$stmt = $pdo->prepare('SELECT * FROM user WHERE username = ? AND password = ?');
$stmt->bindValue(1, $username);
$stmt->bindValue(2, $password);
// Execute it!!!
if ($stmt->execute()) {
$row = $stmt->fetch(PDO::FETCH_OBJ);
if ($row) {
// And don't call fetch() again, since you would already have advanced
// the record pointer in the first fetch() above. If one record was returned,
// this one would always be FALSE.
//$row = $stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION['username'] = $row['username'];
$_SESSION['loggedin'] = 'YES';
$_SESSION['location'] = $row['location'];
echo "2"; //logged in
}
// else execute failed...
}
are you sure session.use_cookies = 1 in php.ini?
please make sure have name is PHPSESSION cookie.

Convert MySQL login script to PDO

I've written a functional login script using MySQL. However, I've now been told that it needs to be done using PDO, and I've a functional PDO connection:
function getConnection()
{
$userName = '*****';
$password = '*****';
$dbname = '******';
$db = new PDO("mysql:host=localhost;dbname=$dbname", $userName, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $db;
However I've no idea how to convert the login query to PDO.
if (isset($_REQUEST['attempt']))
{
$user = $_POST['user'];
$password = $_POST['password'];
$qry = mysql_query
("SELECT *
FROM subscriber
WHERE email = '$user'
AND password = '$password'")
or die(mysql_error());
$total = mysql_num_rows($qry);
if ($total > 0)
{
session_start();
$_SESSION['user'] = 'yes';
header('location: account.php');
exit;
}
else
{
// Do nothing.
}
}
How can I do it?
To get you started:
$db = getConnection();
$stmt = $db->prepare("
SELECT * FROM subscriber WHERE email = :email AND password = :password
");
$stmt->bindParam(":email" , $user );
$stmt->bindParam(":password", $password);
$stmt->execute();
$total = $stmt->rowCount();
Non-bloated version:
$stm = $pdo->prepare("SELECT * FROM subscriber WHERE email = ? AND password = ?");
$stm-> execute($_POST['user'], $_POST['password']);
if ($id = $stm->fetchColumn()) {
session_start();
$_SESSION['user'] = $id;
header('location: account.php');
exit;
}
You can also use this example if you would not like to use bindParam. But I extracted it from #eggyal's answer. Great thanks go to eggyal.
<?php session_start();
include_once('pdo.inc.php');
$username = (isset($_POST['username']))? trim($_POST['username']): '';
$password = (isset($_POST['password']))? $_POST['password'] : '';
$pas = md5($password);
$redirect = (isset($_REQUEST['redirect']))? $_REQUEST['redirect'] :
'view.php';
$query = ("SELECT username FROM site_user WHERE username=:username
AND password =:password");
$query_login = $con->prepare($query);
$query_login->execute(array(
':username'=>$username,
':password'=>$pas));
$result = $query_login->rowCount();
if($result>0)
{
$_SESSION['username'] = $username;
$_SESSION['logged'] = 1;
echo "success";
}
else {
// Set these explicitly just to make sure
echo 'User name invalid';
}
?>

How to make this function work for a username or email as well?

I have the following function that I use to check a user login, at it's state it can only check the username and the password:
public function checkUserLogin($username, $password) {
$password = hash_hmac('sha512', $password, $this->salt($username, $password));
$sql = 'SELECT user_username,user_level FROM users WHERE user_username = ? AND user_password = ?';
// Check Login Attempts
if (isset($_SESSION['attempts']) && $_SESSION['attempts'] >= NUMBER_OF_ATTEMPTS) {
$lockdown = true;
$message['lockdown'] = true;
$message['message'] = SYSTEM_LOCKDOWN_MESSAGE;
return json_encode($message);
} else {
if ($stmt = $this->connect->prepare($sql)) {
$stmt->bind_param('ss', $username, $password);
$stmt->execute();
$stmt->bind_result($username, $admin);
if ($stmt->fetch()) {
$_SESSION['member_logged_in'] = true;
$_SESSION['username'] = $username;
$_SESSION['admin'] = $admin;
$_SESSION['attempts'] = 0;
$stmt->close();
$ip = $this->getIP();
$sql = "UPDATE users SET user_last_login_date = NOW(), user_last_login_ip = '$ip' WHERE user_username = '$username'";
if ($stmt = $this->connect->prepare($sql)) {
$stmt->execute();
$stmt->close();
} else {
$error = true;
$message['error'] = true;
$message['message'] = CANNOT_PREPARE_DATABASE_CONNECTION_MESSAGE;
return json_encode($message);
}
$error = false;
if($_SESSION['admin']==1){
$message['level'] = true;
}
$message['error'] = false;
$message['message'] = SUCCESFUL_LOGIN_MESSAGE;
return json_encode($message);
} else {
#$_SESSION['attempts'] = $_SESSION['attempts'] + 1;
$error = true;
$message['error'] = true;
$message['message'] = FAILED_LOGIN_MESSAGE;
return json_encode($message);
}
}
}
}
Making abstraction of all the functions that are included there and other variables, I need to know if I can make this function work for the username as well for the email.
What I mean is, I want to give the user the chance to login either by his / her email or by his / her username. Is that possible to do to my function, and if yes how ?
It sounds like you want WHERE (user_username = ? OR user_email = ?).
You will need to retrieve the salt from the database, though.
Best practice is to use a long sequence of cryptographically secure random bytes as salt, not the username, so you should be doing that anyway.
I suppose you could modify the query to check $username against both the username AND email fields in the database, e.g. something like
SELECT user_username,user_level
FROM users
WHERE (? IN (user_username, user_email)) AND user_password = ?';
Check for the existence of # and change your query accordingly:
if (strpos($username, '#') === false) {
$nameField = 'user_username';
} else {
$nameField = 'user_email';
}
$sql = 'SELECT user_username,user_level FROM users WHERE '.$nameField.' = ? AND user_password = ?';
The other issue is the salt being based on the username. This will obviously fail if the user decides to switch to the email address. As has been suggested, use a separate salt (unrelated to the username) and add an extra query upfront to retrieve it.
$query = "
SELECT
`user_username`,
`user_level`
FROM
`users`
WHERE
(
`users`.`user_username` = '".mysql_real_escape_string($user)."'
AND
`users`.`user_password` = '".mysql_real_escape_string($pass)."'
)
OR (
`users`.`user_email` = '".mysql_real_escape_string($user)."'
AND
`users`.`user_password` = '".mysql_real_escape_string($pass)."'
)
";
Just make the query like this. I'd advice using the mysql_real_escape_string as it makes your code better protected against SQL-injection (read-up on that!).
From this point on, you can continue with your code.

PDO script to get the amount of rows not working?

I'm new to PDO PHP (just started today). I am attempting too write a login function, but it is returning false, even though i know the credentials are correct.
I think is is the attempt to get the amount of rows which is tripping the script up, can you help?
function check_login($email, $username, $password)
{
$host = 'localhost';
$port = 3306;
$database = 'example';
$username = 'root';
$password = '';
$dsn = "mysql:host=$host;port=$port;dbname=$database";
$db = new PDO($dsn, $username, $password);
$password = md5($password);
$statement = $db->prepare("SELECT * FROM users WHERE email = ? or username = ? and password = ?");
$statement->execute(array($email, $username, $password));
while ($result = $statement->fetchObject()) {
$sql = "SELECT count(*) FROM users WHERE email = ? or username = ? and password = ?";
$result1 = $db->prepare($sql);
$result1->execute(array($email, $username, $password));
$number_of_rows = $result1->fetchColumn();
if ($number_of_rows == 1)
{
$_SESSION['login'] = true;
$_SESSION['uid'] = $result->uid;
return TRUE;
}
else
{
return FALSE;
}
}
}
This:
WHERE email = ? or username = ? and password = ?
... equals this:
WHERE email = ? or (username = ? and password = ?)
... due to operator precedence. That means that if you validate with an e-mail address, you are not required to provide a valid password to log in.
Once you've found out whether the user exists, you make a second query to count the number of matching users. The database table should not be able to hold duplicate users in the first place! Columns username and email should be defined as unique indexes.
There's no point in using a while loop if it's going to return in the first iteration. It may work, but it's confusing.
This should be enough:
$statement = $db->prepare('SELECT uid FROM users WHERE (email = ? or username = ?) and password = ?');
$statement->execute(array($email, $username, $password));
if ($result = $statement->fetchObject()) {
$_SESSION['login'] = true;
$_SESSION['uid'] = $result->uid;
return TRUE;
}else{
return FALSE;
}
Edit: BTW, you should not be storing passwords in plain text. Countless sites have been hacked and their passwords stolen. Google for salted passwords.

Categories