Check if mysql entry exits then DELETE - php

I'm kind of a stuck in searching for a solution.
I need to check if an input data $coupon from the form (after "post" action) equals data in the existing MySQL table called Serial, in the row $Coupon. If those two entries match i need the one in table "Serial" removed (DELETED From). In the other case I need to display an Error, maybe like echo "The coupon number you've entered is invalid".
Now i have the following code, but it doesnt do the check.
$query4="SELECT EXISTS(SELECT 1 FROM serial WHERE Coupon='$coupon')";
$result = mysql_query($query4);
if($result){
echo "Bravo!";
}
else{
"The coupon number you've entered is invalid";
exit;
}
// Delete data from mysql
$query2="DELETE FROM serial WHERE Coupon = '$coupon'";
$result = mysql_query($query2);
// if successfully insert data into database, displays message "Successful".
if($result){
echo "Some info";
}
else {
die(mysql_error());
}
Appreciate any ideas greatly!

You've created a race condition for yourself. The fact that the coupon exists when you run the SELECT statement does not mean that it will exist when you run the delete statement, especially if this is a web app, or multi-threaded/multi-process.
The DELETE statement deletes rows from tbl_name and returns a count of the number of deleted rows. This count can be obtained by calling the ROW_COUNT() function.
Run your DELETE unconditionally, then use the ROW_COUNT to see if it was there and got deleted or wasn't ever there.

First of all phase out mysql_* functionality or you have bigger problems than checking the result. Your code is vulnerable to SQL Injection. Use PDO or MySQLi instead.
Secondly, why do you need EXISTS in the first query at all?
Here is the solution in PDO:
$query = 'SELECT 1 FROM serial WHERE Coupon = :coupon';
$stmt = PDO->prepare($query);
$stmt->bindParam(':coupon', $coupon, DB::PARAM_STR);
$stmt->execute();
if ($stmt->rowCount() > 0) {
//query 2
$query2 = "DELETE FROM serial WHERE Coupon = :coupon";
$stmt2 = PDO->prepare($query2);
$stmt2->bindParam(':coupon', $coupon, DB::PARAM_STR);
if ($stmt2->execute()) {
echo 'Success';
} else {
echo 'Unable to Delete';
}
} else {
echo 'Selected Coupon Is Invalid';
}
OR MORE SIMPLY IN ONE QUERY:
$query = 'DELETE FROM serial WHERE coupon = :coupon';
$stmt = PDO->prepare($query);
$stmt->bindParam(':coupon', $coupon, DB::PARAM_STR);
if ($stmt->execute()) {
echo 'Success';
} else {
echo 'failure, invalid coupon';
}

You can actually just do SELECT 1 FROM serial...
Then:
$result = mysql_query($query4);
if (mysql_num_rows($result)) {
If it returns a row, you know it exists. You can also add LIMIT 1 to the query to make it faster.
By the way, your code is vulnerable to injection. You should use properly parameterized queries with PDO or mysqli.

Following up from mluebke's answer:
// Delete data from mysql
$query="DELETE FROM serial WHERE Coupon = '$coupon'";
mysql_query($query);
//Did we delete something?
if (mysql_affected_rows()) {
echo "Bravo!";
}
else{
"The coupon number you've entered is invalid";
exit;
}
http://www.php.net/manual/en/function.mysql-affected-rows.php
http://dev.mysql.com/doc/refman/5.5/en/information-functions.html#function_row-count

Related

php & mysql please select an other date- message is not appearing

I have two issues and both are linked. First, "already booked - please select another date" is not appearing, if two clients select the same product (pg_no) and date (Date). These fields are UNIQUE CONSTRAINT.
Second, when data is inserted or submitted localhost shows complete address
http://localhost/lstcomp/index.php?note=submitted. But when it fails the localhost shows only : http://localhost/lstcomp/
<?php
//connecting string
include("dbconnect.php");
//assigning
$name = $_REQUEST['Name'];
$tele = $_REQUEST['Tele'];
$city = $_REQUEST['City'];
// UNIQUE CONSTRAINT
$pg_no = $_REQUEST['pg_no']; //product
$date = $_REQUEST['Date']; //date
//checking if pg_no and Date are same
$check = mysqli_query($db_connect, "SELECT * FROM lstclient WHERE pg_no='{$pg_no}', Date='{$date}'");
{
echo "Already booked please select another date<br/>";
}
//if not same then insert data
else
{
$query = mysqli_query($db_connect, "INSERT INTO lstclient(pg_no,Name,Tele,City,Date) VALUES('$pg_no','$name','$tele','$city','$date')") or die(mysql_error());
}
mysqli_close($db_connect);
// messaging
if ($query) {
header("location:index.php?note=failed");
} else {
header("location:index.php?note=success");
}
?>
There are a few problems:
The file fails to parse because of the dangling else; it's not paired with an if-statement.
{
echo "Already booked please select another date<br/>";
}
//if not same then insert data
else
{
$query = mysqli_query($db_connect, "INSERT INTO lstclient(pg_no,Name,Tele,City,Date) VALUES('$pg_no','$name','$tele','$city','$date')") or die(mysql_error());
}
It looks like you're intending to use the result from your SELECT statement ($check), however...
The SELECT statement is invalid; WHERE clauses are separated with AND or OR, not commas.
When inserting the row into the database table, you're dying on mysql_error when you've been using the mysqli extension.
You're vulnerable to SQL injection attacks; if pg_no happened to be '; DELETE FROM users; --, as an example, your user table would be deleted. You're already using the mysqli extension, so use parameter binding and prepared statements. Reference

Email is already in database, returns as if it isn't

Here is some background information on what I'm trying to do here. I'm try to create a registration form for my website (successful so far until this point). Data can be entered into the DB. The only thing I'm trying to do now is prevent duplicate email/usernames from being entered into the db. Through much stackoverflow research, I have found and tested the following code:
$query = "SELECT COUNT(*) AS num_rows FROM users WHERE email = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $email);
if ($stmt->execute()) {
return $stmt->num_rows;
}
What I then do is following:
if(user_exists($user_email) > 0) {
echo "Email already exists!";
}
But is passes by this if statement as if the email does exist in the database!
The email I'm trying to enter, for my tests is testemail#testemailweb.com which is already in the database! Would someone possibly point out where I have messed up in my code? Is there a silly mistake that I could have possibly done when trying to perform this?
The fix for your particular problem here is by not using COUNT(*) as mentioned by John and not depend on mysqli_stmt->num_rows by using a buffered result set:
$query = "SELECT * FROM users WHERE email = ?";
$stmt = $mysqli->prepare($query);
$stmt->bind_param("s", $email);
return $stmt->execute() && $stmt->store_result() && $stmt->num_rows > 0;
Addendum
The only thing I'm trying to do now is prevent duplicate email/usernames from being entered into the db
You will want to use table constraints to prevent this (not just from the app, but anything else that can access the database). This has the added benefit of guarding against race conditions.
ALTER TABLE users ADD UNIQUE(email);
This will raise an error if you attempt to insert a row with an email value that already exists. You can check for this error on the application side and do whatever you want with it.
Your query will always return 1 row. COUNT(*) will return a result set even if only to report no rows match your query. As a result user_exists() always returns 1.
Change your query to:
$query = "SELECT * FROM users WHERE email = ?";
Now if no rows match your query $stmt->num_rows will be 0 so user_exists() will return 0.
change:
if ($stmt->execute()) {
return $stmt->num_rows;
}
What I then do is following:
if(user_exists($user_email) > 0) {
echo "Email already exists!";
}
to
$j=0;
if ($stmt->execute()) {
$j= $stmt->num_rows;
} else {
echo "Email already exists!";
}

Unable to INSERT any records in MYSQL from PHP

So I am trying to develop an app and I need an API, so I am trying now PHP in order to pass my variables from the app to the MYSQL. I am trying with $_GET first in order to see if everything works fine. I tried to pass variables to the database through MYSQL Workbench and then from the app and worked fine. But, when I emptied the table and tried again it didn't work! So I am guessing that my loop doesn't respond well to the fact that my table is empty(?)
This is the code that checks for the email and username if exists and if not insert the variables:
$result = 'notSet';
$query=mysql_query("SELECT * FROM project");
while ($row = mysql_fetch_assoc($query)) {
if(strcmp($row['email'],$email)==0){ //strcmp uses two strings and it returns an integer, if 0 then no differences if more than 0 then there are
$result = 'Email exists';
}else{
if(strcmp($row['username'],$username)==0){
$result = 'Username exists';
}else{
//encryption
$insert = mysql_query("INSERT INTO project VALUES ('$userid', '$fullname','$username','$password','$course','$year','$age','$email')");
$result = 'Registered';
session_start();
$session = session_id();
$SESSION['username']=$username;
}
}
}
Any ideas??
Your table is empty. $query is returning false. Because of this your loop is not executed. You should change the code like this:
if($query){
while(){
//check username and email
}
}
else{
// execute insert query
}
Can you try this code:
$result = 'notSet';
$query = mysql_query("SELECT * FROM project WHERE email = '$email' OR username = '$username' ");
if(mysql_num_rows($query) === 0 ){
$insert = mysql_query("INSERT INTO project VALUES ('$userid', '$fullname','$username','$password','$course','$year','$age','$email')");
$result = 'Registered';
session_start();
$session = session_id();
$SESSION['username']=$username;
}
else{
$result = 'Username or Email exists';
}
We should add single quotes ' only if field type is not integer type. For eg if userid field is integer type and rest of fields are not integer type then query will be
$insert = mysql_query("INSERT INTO project VALUES ($userid, '$fullname','$username','$password','$course','$year','$age','$email')") or die(mysql_error());
thanks
First: you should switch to PDO or mysqli, because the mysql_* functions are deprecated. Please follow the links in Shais comment.
To get the INSERT done, you've got to change your logic. With your code right now, it will never be executed for an empty resultset. You could do it so:
$query=mysql_query("SELECT * FROM project");
if (mysql_num_rows($query) > 0) {
// we've got results, let's loop through the resultset
while($row = mysql_fetch_assoc($query)) {
// do something with the result
}
}
else {
// we've got no results,
// do the insert
}
mysql_query will return a resource for SELECT type queries. A resource evaluates in PHP to true. You can use mysql_num_rows() to check, whether your resultset is not empty.
Excerpt from the linked manual:
Use mysql_num_rows() to find out how many rows were returned for a
SELECT statement
PS: Please consider the content of the red box.
<?php
$query=mysql_query("INSERT INTO project set id=$userid,
'fullname'=$fullname,
'username'=$username,
'password'=$password,
'course'=$course,
'year'=$year,
'age'=$age,
'email'=$email
");
?>

Second prepared statement is not firing

thanks for your time.
Below I have two prepared statements, query & query2;
con is the connection var
The first query is running perfectly and updating the database.
The second query is not updating anything, although it is not giving any error.
When I look at the second query that is logged after a "successful" run, the inserted variable is looking like an empty string. i.e. RESTI=''
Why is this happening? Is my code in the right order for the second query to run?
$row = 1;
$con=mysqli_connect("connect info");
if (mysqli_connect_errno())
{
//echo "Failed to connect to MySQL Error 1: " . mysqli_connect_error();
//error reporting done here
}
else
{
$con->autocommit(false);
$query = $con->prepare("UPDATE table where `INDEX`=?");
$query2 = $con->prepare("UPDATE table2 where (SELECT column from table where`RESTI`=?)");
$query->bind_param('i', $row);
$query2->bind_param('i', $row);
if($query->execute() == false)
{
//Failed!
/ERROR HANDLING
}
else
{
//SUCCESS
}
if($query2->execute() == false)
{
//Failed!
/ERROR HANDLING
}
else
{
//Success
}
$con->commit();
$query->close();
$query->close();
}
mysqli_close($con);
Here is how your update statement should be:
"UPDATE table SET column=<new value to set> WHERE INDEX=?"
"UPDATE table2 SET <col to update>= (SELECT column from table where`RESTI`=?) WHERE condition
Make sure RESTI is an unique field and the subquery would only return scalar value

Getting number of rows and data of that row in a single query using PDO in PHP

I have a log-in system where initially I am checking whether the username/password combination is correct and then fetching the columns to set session variables
Here is my code
$sql='select uid,name from users where username=? and password=?';
$query=$con->prepare($sql);
$result=$query->execute(array($username,$password));
$query->setFetchMode(PDO::FETCH_ASSOC);
//check if a single row is returned
if(($query->fetchColumn())===1)
{
//set session variables
header('Location: lading_page.php');
}
else echo "Invalid username/password";
1) fetchColumn() is giving wrong result as 3 (though I have single row matching that parameters and 15 coulmns per row) whereas if the $sql had been
$sql='select count(*) from users where username=? and password=?';
gives correct answer as 1 Why?
2) I saw the php manual and I found that rowCount() is gauranteed only for DML queries and it suggests workaround for SELECT but it costs 2 queries per login.
Is there a way I can do using single query?
EDIT
Now I am using something like this and it seems to work fine but few problems .see comments
$sql='select uid,name from users where username=? and password=?';
$query=$con->prepare($sql);
$result=$query->execute(array($username,$password));
$rows= $query->fetchAll(PDO::FETCH_ASSOC);
if(count($rows)===1)
{
//I reached here
echo $_SESSION['id']=$rows['uid']; //undefined index uid
echo $_SESSION['name']=$rows['name'];//undefined index name
//header('Location: landing_page.php');
}
else $error="Invalid username/password";
hope i got you right on this.
try it with Fetch all
$rows = $query->fetchAll(PDO::FETCH_ASSOC);
in your case
$sql='select uid,name from users where username=? and password=?';
$query=$con->prepare($sql);
$result=$query->execute(array($username,$password));
// check if a single row is returned
// i guess to avoid the warnings you can just set the array befor like
// $row = array();
// or put # befor the VARS in the TRUE statement
$rows = $query->fetchAll(PDO::FETCH_ASSOC));
/**
if you have more than one result you can look at them like this
foreach ($rows as $row)
{
echo $row['uid'];
}
**/
if((count($rows)===1)
{
echo $_SESSION['id']=#$rows['uid'];
echo $_SESSION['name']=#$rows['name'];
// header('Location: lading_page.php');
}
else echo "Invalid username/password";
fetchColumn() - Returns a single column from the next row of a result set. It's not a number of resulting rows like in "select count(*) ...", it's the value of (in your case) first column (uid) in a result row.

Categories