I need a second pair of eyes on this. I can NOT figure out why this function works just fine:
function get_password($db, $id) {
try {
$sql = $db->prepare('SELECT password FROM employee
WHERE employee.emp_id = ?');
$sql->bindParam(1, $id);
$sql->execute();
$password = $sql->fetchColumn();
} catch(Exception $e) {
echo $e->getMessage();
die();
}
return $password;
}
and this function fails on fetchColumn():
function get_name($db, $email) {
try {
$sql = $db->prepare('SELECT login
FROM employee
WHERE email = ?');
$sql->bindParam(1, $email);
$sql->execute();
$user_name = $sql->fetchColumn(0);
} catch(Exception $e) {
echo $e->getMessage();
die();
}
return $user_name;
}
I have verified the following:
I am trimming the email, so no extra white space is in there
the query works from the command line
the prepare() statement is successful and errorInfo() returns nothing
the bindParam() statement returns true and errorInfo() returns nothing
the execute() statement returns 1 row and errorInfo() returns nothing
the fetchColumn(0) statement returns False (ARGH!!!!) but errorInfo() still returns nothing.
I have also tried using just fetchColumn(), fetchAll, and other fetch attempts.
I have also tried re-writing in the SELECT to this:
'SELECT employee.login FROM employee WHERE employee.email = ?'
but results are the same.
Is there some concept here I'm missing? Any other ideas of how I might debug this?
Related
So I am grabbing the amount of rows in a specific table where the username is already in the database like so:
$second_sql = $db->prepare("SELECT * FROM users WHERE username = :username");
$second_sql->bindParam(':username', $username);
$second_sql->execute();
if($second_sql->rowCount() == 1) {
$db = null;
header("Location: ../login/");
} else {
$statement->execute();
$db = null;
}
The problem is it's not working. If you need more of the script just tell me.
Some databases does not report the row count with PDO->rowCount() method.
SQLite, for instance.
So don't use rowCount(); doing so makes your code less portable.
Instead use the COUNT(*) function in your query, and store the result in a variable.
Finally, use that variable to fetch the one and only column (users) using the fetchColumn() method.
So you can play with this:
try {
$second_sql = $db->prepare("SELECT COUNT(*) from users WHERE username = :username");
$second_sql->bindParam(':username', $username, PDO::PARAM_STR);
$second_sql->execute();
$count = $second_sql->fetchColumn();
} catch (PDOException $e) {
// Here you can log your error
// or send an email
// Never echo this exception on production
// Only on development fase
echo "Error: " . $e->getMessage();
}
if ($count) {
$db = null;
header("Location: ../login/");
} else {
$statement->execute();
$db = null;
}
Perhaps you wanna test you condition for a single row:
if ($count == 1)
Hope this helps you.
Cheers!
I am trying to insert some data to the mysql database
$db = new DataBase($config);
// connect to the database RETURNS true if success false if fails
$conn = $db->connect();
// check whether the connection is successfull or not...
if ($db->isConnected())
{
//prepare the query
$query = 'INSERT INTO scoreboard (score) VALUES(:score) WHERE username=:username';
$bindings = array(
'score' => $score,
'username' => ($_SESSION['username'])
);
// call the query function from db class and retrieve the results as an array of rows.
$results = $db->setData($conn,$query,$bindings);
if ($results)
echo "Your Score is Updated!";
else
echo "Your Score is Not Updated!";
}
Heres what setData() does :
function setData($conn,$query,$bindings)
{
try {
// prepare the query
$stmt = $conn->prepare($query);
//binde the query with the data .here the data is $bindings
$stmt->execute($bindings);
return ( $stmt->rowCount() > 0 )
// return the result if the query is success else return false.
? $stmt
: false;
}
catch(Exception $e) {
// return error if something goes wrong
return false;
}
}
Everytime I run this script I get "Your Score is Not Updated" as output.
Where I am going wrong?
Is that the $_SESSION['username'] causing trouble?
Any help with proper explanation will be highly appreciated!
you are updating or inserting? try your query manually with static data on phpmyadmin, then make sure your session is set & return true if successfully data inserted
I'm creating an authentification file with php and mysql, but I have this mistake in this line:
$stmt2->bind_param('ss',$twitter_id, $name);
The error message is
Call to a member function bind_param() on a non-object in ...
Where's my mistake?
$name in my database is a VARCHAR
$twitter_id in my database is a VARCHAR
$bd is my database connection
If a user is already registered, it should show me a message saying "User already registered", and if the user isn't registered, it should insert a new id and name in my database.
session_start();
if (!isset($_SESSION['userdata'])) {
header("location: index.php");
} else {
$userdata = $_SESSION['userdata'];
$name = $userdata->name;
$twitter_id = $userdata->id;
$stmt = $bd->prepare("SELECT ID_TWITTER FROM USERS");
$stmt->execute();
$stmt->bind_result($checkUser);
if ($stmt->fetch()) {
if($checkUser!==$twitter_id){
$cSQL = "INSERT INTO USERS (ID_TWITTER, FULL_NAME) VALUES(?,?)";
$stmt2 = $bd->prepare($cSQL);
$stmt2->bind_param('ss',$twitter_id, $name);
$stmt2->execute();
$stmt2->close();
} else {
echo "User already exits";
}
}
$stmt->close();
}
Could it be a typo? does $bd exist or should it be $db ?
Shameless plug: I do this exact thing in a project I have on github. Feel free to use the classes for whatever you like; they are mostly copy-pastable.
Your real issue is that $bd->prepare() returned false.
Check that you actually called it correctly and set it to new mysqli(*params)
The error Call to a member function ... on a non-object in ... means that $db is not an object, which means that it was not instantiated to an object. Thus, $this->method() isn't possible. bind_param(string $format, mixed &*vars); uses pass-by-reference and if this fails, it throws an error.
Try it yourself by sticking this in there:
$stmt->bind_param("ss", "string", "string");
To get around this issue where it can fail, check if $db->prepare() returns true:
if ($query = $bd->prepare($sql)) {
//stuff
}
In addition, in the first query you do it is probably not a good idea to be adding the overhead of a prepare for a single query that only checks row count without user input.
Solved : it works now
$stmt = $bd->prepare("SELECT ID_PROVIDER FROM USERS WHERE ID_PROVIDER = ?");
$stmt->bind_param('s', $twitter_id);
$stmt->execute();
$stmt->bind_result($checkUser);
while ($stmt->fetch()) {
$result = $checkUser;
}
if (empty($result)) {
$cSQL = "INSERT INTO USERS (ID_TWITTER, FULL_NAME)
VALUES(?,?)";
$stmt2 = $bd->prepare($cSQL);
$stmt2->bind_param('ss', $twitter_id, $name);
$stmt2->execute();
$stmt2->close();
}else {
echo "User already exits";
}
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.
I am fighting now like hours to figure out how to make possible to use SHA1 + PDO + Prepared Statement combination and still be able to log in to web page :) So my question is how to do so? Here is my code:
if (!empty($user) && !empty($password))
{
$password = $this->doHash($user, $password);
$stmt = $db_login->prepare("SELECT COUNT(*) FROM account WHERE username=:user AND sha_pass=:password");
$stmt->bindValue(':user', $user, PDO::PARAM_STR);
$stmt->bindValue(':password', $password, PDO::PARAM_STR);
$stmt->execute();
$results_login = $stmt->fetchAll(PDO::FETCH_ASSOC);
if ($results_login['COUNT(*)'] > 0)
{
$_SESSION['user_name'] = $results_login['username'];
$_SESSION['user_id'] = $results_login['id'];
return true;
}
else
{
return false;
}
}
else
{
return false;
}
My function doHash looks like this:
public function doHash($user, $password)
{
return sha1(strtoupper($user).":".strtoupper($password));
}
So my problems are: $results_login*** never processes with the SELECT COUNT(*) version, and with SELECT * version it processes sometimes, but not always. So how do I put it together to work as intended, result in true, and fill all the variables I need? Thank you.
Your SQL statement is only counting, it is not selecting the username and id, you would need to use this as your SQL statement, or something like it:
"SELECT * FROM account WHERE username=:user AND sha_pass=:password"
For your password binding, the following should work just fine. I would also use rowCount and only fetch, not fetchAll. Give this a try and see if it works.
$stmt->bindValue(':password', doHash($user,$password), PDO::PARAM_STR);
$stmt->execute();
if($stmt->rowCount()==1){
$results_login=$stmt->fetch(PDO::FETCH_ASSOC);
$_SESSION['user_name'] = $results_login['username'];
$_SESSION['user_id'] = $results_login['id'];
return true;
}else{
return false;
}