I am student and I work on a noteapp. I made 2 methods in my DB-Handler within my Login-Mask for users to Login or Register.
<?php
class DBHandler
{
var $hostname;
var $user;
var $pw;
var $db;
var $connection;
function connectToDB($hostname,$user,$pw,$db){
$this->hostname = $hostname;
$this->user = $user;
$this->pw = $pw;
$this->db = $db;
$this->connection = new mysqli($this->hostname,$this->user,$this->pw,$this->db);
if ($this->connection->connect_error) {
die('Failed to connect' . $this->connection->connect_error);
}
$this->ensureNotesTable();
$this->ensureUsersTable();
}
function ensureUsersTable(){
assert($this->connection);
$queryCreate = "CREATE TABLE IF NOT EXISTS users(id INT(5) PRIMARY KEY AUTO_INCREMENT, username VARCHAR(100) NOT NULL, password VARCHAR(100) NOT NULL)";
$this->connection->query($queryCreate);
}
function ensureNotesTable(){
assert($this->connection);
$queryCreate = "CREATE TABLE IF NOT EXISTS notesnew(id INT(5) PRIMARY KEY AUTO_INCREMENT, title VARCHAR(100) NOT NULL, content VARCHAR(100) NOT NULL, userid INT(5) NOT NULL)";
$this->connection->query($queryCreate);
}
function ensureUsername($username,$password){
assert($this->connection);
echo $username;
$query = "SELECT * FROM users WHERE username = (?)";
$statement = $this->connection->prepare($query);
$statement->bind_param('s',$username);
$results = $statement->execute();
echo $this->connection->errno.'-'.$this->connection->error;
if(mysqli_num_rows($results) >= 1){
echo $this->connection->errno.'-'.$this->connection->error;
echo "Username already exists";
} echo "Username is free!";
$this->addUser($username,$password);
}
function addUser($username,$password){
assert($this->connection);
$queryCreate = "INSERT INTO users(username, password) VALUES (?,?)";
$statement = $this->connection->prepare($queryCreate);
$statement->bind_param('ss', $username, $password);
return $statement->execute();
echo "You have been registered!";
}
function getUserId($username){
assert($this->connection);
$queryCreate = "SELECT id FROM users WHERE username = $username";
$row = $this->connection->query($queryCreate);
$userid = mysqli_fetch_row($row);
return $userid[0];
}
function addNote($title, $text, $userID){
assert($this->connection);
$queryCreate = "INSERT INTO notesnew(title, content, userid) VALUES (?,?,?)";
$statement = $this->connection->prepare($queryCreate);
$statement->bind_param('ssi', $title,$text,$userID);
return $statement->execute();
}
}
Within ensureUsername I wanna check if the username which is used for the registration has already been picked by another user.
Within addUser I wanna do the Insert statement, to add the user to the database, if the username is free.
I tried about 3 hours today but it always gives me errors. I hate it! Maybe im just too stupid for it.
At the moment its saying:
Warning: mysqli::query() expects parameter 1 to be string, object
given in
C:\Users\ReallySorry\PhpstormProjects\NoteAppMongo\DBHandler.php on
line 57 0- Warning: mysqli_num_rows() expects parameter 1 to be
mysqli_result, null given in
C:\Users\ReallySorry\PhpstormProjects\NoteAppMongo\DBHandler.php on
line 60
Does anybody know what im doing wrong?
Thanks ...
The depressed student
Your problem is here:
$statement = $this->connection->prepare($query);
$statement->bind_param('s',$username);
$results = $this->connection->query($statement)
When you're using prepared statements (well done – so many people here don't!) you need to use the execute() method on your statement rather than calling query() on your connection. So, this should work:
$results = $statement->execute()
Some minor changes to the original -
function ensureUsername( $username=false, $password=false ){
$rv=false;/* Return Value */
if( !assert( $this->connection ) or !$username or !$password ) return $rv;
$db=$this->connection;/* shorthand for laziness */
$sql = "select `username` from `users` where `username`=?;";
$stmt = $db->prepare( $sql );
$stmt->bind_param('s', $username );
$res = $stmt->execute();
$stmt->store_result();
if( $res ){
$rv=( $stmt->num_rows > 0 ) ? 'Sorry, that Username already exists!' : $this->addUser( $username, $password );
}
$stmt->free_result();
$stmt->close();
echo $rv;
}
function addUser( $username, $password ){
$db=$this->connection;/* No need for assert now, if the script gets here the db conn must exist */
$sql = "insert into `users` (`username`, `password`) values (?,?);";
$stmt = $db->prepare( $sql );
$stmt->bind_param('ss', $username, $password );
return $stmt->execute() ? 'You have been registered!' : 'Sorry, there was a problem';
}
Related
I store the password, get through a form, into MySQL database via PDO, after having hashed it with password_hash()
(VARCHAR(512) field)
$options = array(
'cost' => 12
);
$password = password_hash($password, PASSWORD_BCRYPT, $options);
Suppose that
$pass = "123Azerty";
//and the hash is
$hash = "$2y$12$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
When I get the password from the database and I verify it with password_verify() it returns always false
...
...
$returnedPWD = $row['password'];
if (password_verify($pass,$returnedPWD)){
echo "TRUE";
} else {
echo "FALSE";
}
...
...
At this point, I tried to do it "manually" in this way
$pass = "123Azerty";
$hash = "$2y$12$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
if (password_verify($pass,$hash )){
echo "TRUE";
} else {
echo "FALSE";
}
And it always returned FALSE
BUT
when I changed
$hash = "$2y$12$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
// into
$hash = '$2y$12$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe';
it worked. Because the hash enclosed in single quotes, is not parsable.
On my understanding, it means that the hash taken from database, it is interpreted as parsable (double totes) than it doesn't work at all
then I tried to enclose the string out the db int strval():
...
...
$returnedPWD = strval($row['password']);
if (password_verify($pass,$returnedPWD)){
echo "TRUE";
} else {
echo "FALSE";
}
...
...
But it returns always FALSE
reading all the posts related the not functioning of password_verify(), I didn't come up to any valid solution, for me.
Please is there a way to make it work?
Thanks in advance
EDIT 1
I did try with other settings as PASSWORD_DEFAULT but no changes.
I also tried to base64 encode it upfront database storage, then decode it. But nothing changed
EDIT 2
I store the data using PDO with parameters
$query = "INSERT INTO `users` (username, password) VALUES (:username, :password)";
$params = array(
':username' => "$username",
':password' => "$password" // hashed one
);
EDIT 3
Table Structure
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL,
`password` varchar(512) NOT NULL,
`enabled` int(1) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 AUTO_INCREMENT=13 ;
$username = trim($_POST["username"];
$password = trim($_POST["password"];
// Query to insert data
$query = "INSERT INTO `users` (username, password, enabled) VALUES (:username, :password, 1)";
// The very original setup I did use and didn't work out
$param_password = password_hash($password, PASSWORD_DEFAULT);
// Bind parameters
$params = array(
':username' => "$username",
':password' => "$param_password"
);
...
...
// insert into db
$sth = $sql->prepare($query);
// Call MySQL
try {
$sth->execute($params); // Execute the Query
} catch (PDOException $e) {
$mysql_error = 'MySQL connection failed: ' . "<br>" . $e->getMessage();
}
...
...
and here the fundamental lines on how I read from database
...
...
$username_login = trim($_POST["username"]);
$password_login = trim($_POST["password"]);
...
...
$query = "SELECT * FROM `users` WHERE username = :username";
$params = array(
':username' => $username_login
);
$sth = $sql->prepare($query);
try{
$sth->execute($params);
} catch (PDOException $e) {
$mysql_error = 'MySQL connection failed: ' . "<br>" . $e->getMessage();
}
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
foreach ($row as $key => $value) {
global $$key;
$$key = $value;
}
}
...
...
if (password_verify($password_login, $password) and $enabled == 1){
// Password is correct, so start a new session
session_start();
// Store data in session variables
$_SESSION["logged"] = true;
$_SESSION["id"] = $id;
$_SESSION["uname"] = $username_login_;
// Redirect user to welcome page
header("location: index.php");
} else {
// Display an error message if password is not valid
$password_login__err = "The password you entered was not valid. Or you are not enabled";
}
...
...
Your code does not work because of "$password " - it has space at the end. It should be:
$query = "INSERT INTO `users` (username, password) VALUES (:username, :password)";
$params = array(
':username' => $username,
':password' => $password, // hashed one
);
Your manual test does not work because
$hash = "$2y$12$TzpGzy1cKM81pkEr/Mn0SOVA4wn0lr.7PnKFg4SU9Hto0EUiGGRMe";
has double quotes and it interpolates $2y, $12 and $Tz... as variables that leads to empty string. That's why single quotes works.
From your provided information I constructed sample code that does work: Check here
What I am trying to do is allow the user to create a table and I want to add the userID of the user into the first line of the table so I can access it later. However, when trying to insert the ID, I keep getting an error message saying I cannot add it. Here is my code:
<?php
# $db = new mysqli('localhost', 'root', 'secret', 'Pokemon'); //open db
if ($db->connect_error) {
echo 'ERROR: Could not connect to database, error is '. $db->connect_error;
exit;
} else {
echo 'Successful connection established<br />';
}
$deckName = stripslashes($_POST['deckName']); //sql sanitize for each input.
$deckName = $db->real_escape_string($deckName);
$checkQuery = "SELECT userID FROM userInfo WHERE userEmail = ?";
$checkStmt = $db->prepare($checkQuery);
$checkStmt->bind_param("s", $SESSION['userEmail']);
$checkStmt->execute();
if ( ($checkStmt->errno <> 0) || ($checkStmt->num_rows > 0) )
{
$checkStmt->close();
echo 'ERROR: Something is wrong';
exit;
}
$res = $checkStmt->get_result();
$row = $res->fetch_assoc();
$checkStmt->close();
$query = "CREATE TABLE `".$deckName."` (userID int(3), pokeID int(3), pokeName varchar(20), quantity int(1),
PRIMARY KEY (userID) )";
$stmt = $db->prepare($query);
$stmt->execute();
if ($stmt->errno <> 0)
{
$stmt->close();
$db->close();
echo 'ERROR: Could not create table';
exit;
}
$stmt->close();
$query = "INSERT INTO `".$deckName."` (userID) VALUES(?)";
$stmt = $db->prepare($query);
$stmt->bind_param("i", $row['userID']);
$stmt->execute();
if ($stmt->errno <> 0)
{
$stmt->close();
$db->close();
echo 'ERROR: Could not add to database';
exit;
}
$stmt->close();
$db->close();
header("Location: viewCards.php");
?>
It creates the table, but will not insert the userID. I have looked at this trying to find what the issue is, and I would like a fresh set of eyes to look at it if possible.
Use $_SESSION['userEmail'] instead of $SESSION['userEmail'] and there is no session_start()
I am trying to update this section of old MySQL code to run with MySQLi. I am aware that the MySQL_return function was removed and I've tried a couple things but not too sure how to convert this code to run with MySQLi? Any ideas or help would be appreciated.
function user_id_from_username($email_address, $conn) {
return mysql_return(mysqli_query($conn, "SELECT `userid` FROM `users` WHERE `email_address` = '$email_address'"), 0, 'userid');
}
function login($email_address, $password, $conn) {
$userid = user_id_from_username($email_address);
$password = md5($password);
return (mysql_return(mysqli_query($conn, "SELECT COUNT(`userid`) FROM `users` WHERE `email_address` = '$email_address' AND `password` = '$password'"), 0) ==1) ? $userid : false;
}
I have attempted such edits as:
function user_id_from_username($email_address, $conn) {
return mysqli_fetch_assoc(mysqli_query($conn, "SELECT `userid` FROM `users` WHERE `email_address` = '$email_address'"), 0, 'userid');
}
function login($email_address, $password, $conn) {
$userid = user_id_from_username($email_address);
$password = md5($password);
return (mysqli_fetch_assoc(mysqli_query($conn, "SELECT COUNT(`userid`) FROM `users` WHERE `email_address` = '$email_address' AND `password` = '$password'"), 0) ==1) ? $userid : false;
}
But no luck. Any advice or examples?
The method $mysqli->query(); returns a $mysqli_result if the query was executed successfully, FALSE otherwise. Then you can call fetch_assoc(); for get the first row from the query. The resultant array will be in the form of an associative array. Here is some documentation you should read:
http://php.net/manual/en/mysqli.query.php and
http://php.net/manual/en/mysqli-result.fetch-assoc.php
function getIdFromEmail($email) {
$emailSanitized=mysqli_real_escape_string($email);
$mysqli=new mysqli("host","user","password","dbName");
$res=$mysqli->query("SELECT `userid` FROM `users` WHERE `email_address`='$emailSanitized'");
$retArray=$res->fetch_assoc();
return $retArray['userId'];
}
I create this class but i'm newbie in PHP OOP & PDO and i don't know how and where i must to make check to username is valid , email is valid and e.t.c..
This is my code
Class Users {
private $db;
public function __construct(Database $datebase) {
if (!$database instanceOf Database) {
throw new Exeption();
}
$this->db = $datebase;
}
public function userRegistration($username, $password, $email) {
$username = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
$regdate = date('d.m.Y');
$query = $this->db->prepare("INSERT INTO `users` (`username`, `password`, `email`, `regdate`) VALUES (?, ?, ?, ?) ");
$query->bindValue(1, $username);
$query->bindValue(2, $password);
$query->bindValue(3, $email);
$query->bindValue(4, $regdate);
return ($query->execute()) ? true : false ;
}
}
If you want to check something, use Respect/Validation. For example:
$usernameValidator = v::alnum()->noWhitespace()->length(1,15);
$usernameValidator->validate($_POST['username']); //true or false
$passwordValidator = v::alnum()->length(10, null);
$passwordValidator->validate($_POST['password']); //true or false
v::email()->validate($_POST['email']); //true or false
To check if the username or email exist in your database you can use SQL to search the email or username.
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
If the query returns a value than the email or username already exist in your database. From there you can show your own validation.
To check check if user or email exist you don't need another class, just add another method called userExist or emailExist and run a query and then check if you get a result.
public function emailExist($email){
$query = $this->db->prepare("SELECT * FROM users WHERE email = ? ");
$query->bindValue(1, $email);
try{
$query->execute();
//use the if statement and $query->rowCount() to check if there is a result
$rows = $query->rowCount();
if($rows === 1){
return true;
} else {
return false;
}
}catch (PDOException $e) {
die($e->getMessage());
}
}
I am trying to use a function to get the password of the user based on the username that is entered. However I can not seem to get the result to be a string. How to i transfer it to a string? I just want the value that is stored in the password column.
here is the function
public function get_password($username) {
global $pdo;
$query = $pdo->prepare("SELECT `password` FROM `users` WHERE `username` = ?");
$query->bindValue(1, $username);
$query->execute();
$query->fetch(PDO::FETCH_ASSOC);
return $query;
}
i want this because i keep getting a error saying that a parameter that uses the result from this function expects string, array given, so i assume the result from the function needs to be a string not an array
EDIT: I tried adding $query['password'] but it returned an error that said Cannot use object of type PDOStatement as array
Use this:
public function get_password($username) {
global $pdo;
$query = $pdo->prepare("SELECT `password` FROM `users` WHERE `username` = ?");
$query->bindValue(1, $username);
$query->execute();
$password = "";
while($row = $query->fetch(PDO::FETCH_ASSOC))
{
$password = $row['password'];
}
return $password;
}
try this
while($row = $query->fetch(PDO::FETCH_ASSOC))
{
$password = $row['password'];
}