Checking for existing records with MySQLi prepared statement - php

So I have written a script to insert an email address in a table but I want to check if the address already exists. So I begin with a prepared statement:
$statement = $db->prepare("SELECT * FROM `signups` WHERE `signups_email`= ? ");
$statement->bind_param('s',$email);
$statement->execute();
if($statement->num_rows < 1){
$statement->close(); //Free up the SQL result
//do the inserting code
} else {
echo "Email already exists";
}
Trouble is, ($statement->num_rows < 1) seems to always return true, even when I know there is an email in the database. I.e. it doesn't figure out that the address is already in the database.
My connection etc is fine as the //do the inserting code bit works fine.

Take a look at the documentation for mysqli_num_rows.
Returns the number of rows in the result set. The use of
mysqli_stmt_num_rows() depends on whether or not you used
mysqli_stmt_store_result() to buffer the entire result set in the
statement handle.
If you use mysqli_stmt_store_result(), mysqli_stmt_num_rows() may be
called immediately.
It looks like you need to call store_result() before you can check the number of rows.

Your statement fails if the email already exists in the DB. the if() should be
if ($statement->num_rows == 0) {
... email does not exist, insert it
} else {
... at least one record with that email exists
}

Related

PHP: How do I get my IF statement to work with PDO select?

I want my below PDO select to work with the bottom two IF statements?
The first IF I just want to make sure there is no error.
The second IF I want to check how many rows it returns. I know that this number of rows == 0 will not work.
Is there a way to do that?
try {
$conn = new PDO('mysql:host=localhost;dbname=zs', 'zs', 'rlkj08sfSsdf');
$conn ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
echo $e->getMessage();
die();
}
$stmt = $conn->prepare("SELECT * FROM zip WHERE zip_code =:zip1");
$stmt->bindValue(':zip1', $_POST[zipcode], PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
if($rows = "") {
echo "<p><strong>There was a database error attempting to retrieve your ZIP Code.</strong></p>\n";
}
if(number of rows == 0) {
echo "<p><strong>No database match for provided ZIP Code.</strong> Please enter a new ZIP Code.</p>\n";
}
You're interested only in whether there are records containing a particular value. It makes no sense to select everything and count the records in PHP. It's a waste of resources. Imagine what happens if there's a million records.
Solution you're after is to simply ask your database about the COUNT of rows containing a particular value. Your code should be quite simple:
$stmt = $conn->prepare("SELECT COUNT(*) AS num_rows FROM zip WHERE zip_code = :zip");
$stmt->bindValue(':zip', $_POST['zipcode'], PDO::PARAM_INT);
$stmt->execute();
$count = (int)$stmt->fetchColumn();
if($count)
{
echo "Success";
}
else
{
echo "Bummer";
}
Notes:
if successful, the above query will always return 1 row with 1 column, named num_rows which will be 0 for no matching records or an integer larger than 0 if there are records. If you use MySQL native driver with PHP, PHP will correctly represent this value as integer internally. I deliberately put typecasting in, you can remove it (the (int) part) if you have MySQL ND.
if something goes wrong during query execution, an exception will be thrown. The snippet doesn't cover that. You correctly set PDO in exception mode, and along with using bindValue instead of bindParam, this implies you did your research right and you're using PDO correctly which means that error handling should be implemented easily by you in this particular case.

Checking results of PDO statement to run a conditional

I am trying too input a new number into a databasee only if it does not already exist, in order to do this, I am doing the following
if (isset($_POST['Number'])) {
$number = ($_POST['Number']);
$NCheck = "SELECT COUNT(*) FROM `DS_Numbers` WHERE `Number` = '$number' ";
$stmt = $dbCon->prepare($sql);//* prepared statement for result which populates table
$stmt->execute();
$result = $stmt->fetchColumn(0);
if($result > 0){ // if there is a value then block
$ENumber = "This Number already exists";
$errors[] = 'error';
} else {
echo "number done";// echo statement to see that it has reached this
$number1 = ($_POST['Number']);
}
} else {
$errors[] = 'error';
$ENumber = "Please enter only digits from 0-9";
}
What is currently happening is that my PDO statement is not returning, so my result value is always 0, but none of my research has shown that I have an issue with it
any suggestions on where I am going wrong?
I am getting Number from an HTML form on the page, no issues on that side.
First thing to notice is that you are writing your query in a variable called $NCheck, not $sql.
So this line
$stmt = $dbCon->prepare($sql);
should be
$stmt = $dbCon->prepare($NCheck);
Also please note that one of the main advantages in using PDO is to use bound parameters, but you are not doing this and you are in fact exposed to SQL injection since you are just adding that value you get in POST in the query.
If the number must be unique in the table then you should probably add a UNIQUE constraint to the column. You can then just insert the number and if it was not unique the database will return a 'duplicate key' error.
If you use the 'check-first-insert-later' method you are open to race conditions; if two processes try to insert the same number at the same time they will both run the select at the same time and they will both get zero and try to insert, which without a unique constraint will work for both.

How to check the existence of mysql database? [duplicate]

This question already has answers here:
How to check if mysql database exists
(23 answers)
Closed 8 years ago.
$pdo_mysql = new PDO("mysql:host=localhost", "ales", "alespass");
$result = $pdo_mysql->query("SHOW DATABASES LIKE `dbname`");
if ($result) { //not work.
print "no";
} else {
print "yes";
}
You can not use CREATE DATABASE IF NOT EXISTS or new PDO("mysql:host=localhost;db=dbname" ...
You have a typo error in your comment on #robin s answer, I think the condition should be if (!empty($result)) with that exclamation mark. It is printing not exists because $result is not empty when database exists. Therefore using this $result = $pdo_mysql->query("SHOW DATABASES LIKE '" . DB_NAME . "'"); if (!empty($result)) { print "exists"; } else { print "no exists"; } should work. I hope that helps
Manual:
PDO::query() returns a PDOStatement object, or FALSE on failure.
Your query is valid and should never fail (ignoring possible lower level issues).
$result will always evaluate to TRUE-ish, so the flow will always enter the if ($result) block.
(if (empty($result)) makes little to no sense)
You need to check whether the query returns zero row (zero result is not an error).
On second thought:
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
It is safer to do something like this:
if ($result->fetch() === FALSE) {
// result set is empty
}
CREATE DATABASE IF NOT EXISTS
should do the trick. If it doesn't, check for the existence first via
SELECT schema_name FROM information_schema.schemata WHERE schema_name = 'dbname'
it will return you the database name itself, so you can check if the count of the query is > 0, the result is != 0...and so on. However you like.
The problem with your queries is the wrong use of backticks, you need to use single quotes, not backticks.
' instead of `

$result is showing true every time

i just started learning PDO...
function authenticate($username,$password)
{
$result=$this->con->query("select * from user where UserName='".$username."' AND Password='".$password."'");
var_dump($result->rowCount()); //return null
if($result)
echo "hey going great";
else
echo "Hey are you gone mad?";
}
i am calling above function with username and password... but it's returning hey going great part every time if i will pass wrong username and password also...
i tried with $result->rowCount() but it's also returning null value...
Can you suggest me what i am doing wrong here?
You are doing almost everything wrong.
First and foremost, the only reason for using PDO is using placeholders in the query.
You shouldn't also check the query result right in the function. So, make it
function authenticate($username,$password)
{
$sql = "SELECT * FROM user WHERE UserName=? AND Password=?";
$stm = $this->con->prepare($sql);
$stm->execute([$username,$password]);
return $stm->fetch();
}
and then call
if($userdata = $user->authenticate($username,$password))
echo "hey going great";
else
echo "Hey are you gone mad?";
Assuming $this->con is an instance of PDO:
PDO->query() only returns false on failure.
$result will be an instance of PDOStatement, which always evaluates to true
PDOStatement->rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.
Edit: By the way, your application would be more safe, if you use PDO->prepare() (& bound parameters) instead of PDO->query().
if($result)
This will always check for if the variable has any info. When ever you run a query and store in this var , it will store number of rows returned . Even if it is wrong , it will return a neg value which sets the variable.
Basically your if is just checking if the variable exists , it does exist in both cases.
if($result->rowCount()>0){
echo "hey going great";
}else{
echo "Hey are you gone mad?";
}
you can try it as:
$result=$this->con->query("select * from user where UserName='".$username."' AND Password='".$password."'");
var_dump($result->rowCount()); //return null
$num_row=$result->rowCount();
if($num_row > 0)
echo "hey going great";
else
echo "Hey are you gone mad?";

record updated? when $stmt->execute() $stmt->affected_rows

considering the following for my question:
$success = false;
$err_msg = '';
$sql = 'UPDATE task SET title = ? WHERE task_id = ?';
$conn = connect('w'); // create database connection: r= read, w= write
$stmt = $conn->stmt_init(); // initialize a prepared statement
$stmt->prepare($sql);
$stmt->bind_param('si', $_POST['title'], $_POST['id']);
$stmt->execute();
If i want to check if an insert or a deletion was succesfull, i could easily check for the affected_rows, like this:
if ($stmt->affected_rows > 0) {
$success = true;
} else {
$err_msg = $stmt->error;
}
If $stmt->affected_rows equals -1, it means that $stmt->execute() executed correctly but did not insert the record or did not delete the record successfully.
But, what about an update ? What is the correct way to deal with an update?
The way i do it is by checking for the return value :
$isRecordUpdated = $stmt->execute();
if (!$isRecordUpdated) {
// execute failed, therefore NO record updated!
} else {
//execute success, record updated!
}
Is that the correct way you guys are doing it?
It seems to me that there are really two equivalent and correct ways of doing this: either by checking the return value of execute as you do, or by checking the affected_rows value. -1 means the query errored out; 0 means that it did not affect (delete or update) any rows because there were none matching the query.
Since it seems there is no "better" way, you should pick what would be most convenient for your code. If e.g. using one approach over the other means that you can then share code among all types of queries, you might want to pick that one.
Why not store the value from mysql-affected-rows into a property of that object when you call execute()?
http://php.net/manual/en/function.mysql-affected-rows.php

Categories