PHP Form Dedupe Before Insert - php

Hello i have the following code that validates that a form has data in it and then i want to make sure that the Name, Email and Address arent already in my database before i insert it...
Can you tell where i am messing up with the below it is throwing the already exists error even when it is unique data
if($_POST['formSubmit'] == "Submit")
{
$errorMessage = "";
if(empty($_POST['formName']))
{
$errorMessage .= "<li>You forgot to enter a name!</li>";
}
if(empty($_POST['formEmail']))
{
$errorMessage .= "<li>You forgot to enter an email!</li>";
}
if(empty($_POST['formAddress']))
{
$errorMessage .= "<li>You forgot to enter your Address!</li>";
}
if(empty($_POST['formCity']))
{
$errorMessage .= "<li>You forgot to enter your City!</li>";
}
if(empty($_POST['formState']))
{
$errorMessage .= "<li>You forgot to enter your State!</li>";
}
if(empty($_POST['formZip']))
{
$errorMessage .= "<li>You forgot to enter your Zip!</li>";
}
$varName = $_POST['formName'];
$varEmail = $_POST['formEmail'];
$varAddress = $_POST['formAddress'];
$varCity = $_POST['formCity'];
$varState = $_POST['formState'];
$varZip = $_POST['formZip'];
$varDate = $_POST['formDate'];
if(empty($errorMessage))
{
$db = mysql_connect("localhost","root","PASSWORD");
if(!$db) die("Error connecting to MySQL database.");
mysql_select_db("FormData" ,$db);
$dupesql = "SELECT * FROM formdata WHERE (name = '$varName' AND email = '$varEmail' AND address = '$varAddress')";
$duperaw = mysql_query($dupesql);
if($duperaw > 0) {
echo ("$varName already exists in $varAddress \n");
}
else {
$sql = "INSERT INTO formdata (name, email, address, city, state, zip, submitDate) VALUES (".
PrepSQL($varName) . ", " .
PrepSQL($varEmail) . ", " .
PrepSQL($varAddress) . ", " .
PrepSQL($varCity) . ", " .
PrepSQL($varState) . ", " .
PrepSQL($varZip) . ", " .
PrepSQL($varDate) . ")";
mysql_query($sql);
header("location: index.php?success=1");
exit();
}
}
}

Use mysql_num_rows($duperaw) > 0 instead of just $duperaw > 0 to check if your query returned any results.
Also, avoid using mysql_* functions. They are no longer maintained and are deprecated as of PHP 5.5.0. Read this post for a more detailed explanation. Instead, use PDO or MySQLi and learn about prepared statements. This article can help you decide which MySQL API to use.

Related

How would I make this PHP Script SQL Injection Proof? [duplicate]

This question already has answers here:
How can I prevent SQL injection in PHP?
(27 answers)
Closed 5 years ago.
<?php
$conn = mysql_connect("localhost", "root", "") or die ('Error connecting to MySQL!');
mysql_select_db("aspire");
$earnedpoints = false;
$account = $_POST['name'];
$account = mysql_real_escape_string($account);
if ($account == "") {
echo 'Enter an account name!';
exit();
}
$ip = $_SERVER['REMOTE_ADDR'];
$time = time();
$query = mysql_query("SELECT *, SUM(`times`) as amount FROM votingrecords WHERE account='$account' OR ip='$ip'");
$lasttime = mysql_fetch_array($query);
$amount = $lasttime['amount'];
$insertnew = false;
if ($amount == "") {
$insertnew = true;
}
$timecalc = $time - $lasttime['date'];
if (!$insertnew) {
if ($timecalc < 21600) {
echo ' Hello '. $account .' you have already voted with this account ('. $account .') or IP ('. $ip .') in the last 6 hours!';
echo ' Last voted on: '. date('M d\, h:i:s A', $lasttime['date']) .'';
echo '<html>';
echo '<head>';
echo '<meta HTTP-EQUIV="REFRESH" content="10; url=/">';
echo '</head>';
echo '<body>';
echo '<br><br>You will be redirected to the main website in 10 seconds.';
echo '</body>';
echo '</html>';
exit();
} else {
$update = mysql_query("UPDATE votingrecords SET account='$account', date='$time', times=times+1 WHERE ip='$ip'");
if (!$update) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $update;
die($message);
} else {
$earnedpoints = true;
}
}
} else {
$success = mysql_query("INSERT INTO votingrecords (`account`, `ip`, `date`, `times`) VALUES ('$account', '$ip', '$time', 1)");
if (!$success) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $success;
die($message);
} else {
$earnedpoints = true;
}
}
if ($earnedpoints) {
$points = mysql_query("UPDATE accounts SET votepoints = votepoints + 2 WHERE name='$account'");
if (!$points) {
$message = 'Invalid query: ' . mysql_error() . "\n";
$message .= 'Whole query: ' . $query;
die($message);
}
mysql_close($conn);
echo '<html>';
echo '<head>';
echo '<meta HTTP-EQUIV="REFRESH" content="0; url=http://www.gtop100.com/in.php?site=80994">';
echo '</head>';
echo '</html>';
} else {
echo 'There was an error processing your request.';
exit();
}
?>
Hey everyone,
I'm very inexperienced with PHP scripting and I've been told that my script is vulnerable to SQL injection? But I'm not sure how I would make it to be SQL injection proof since I'm not much experienced in that field and i'm afraid I might mess up the code.
Could anyone help me with this? I would greatly appreciate it.
How can I prevent SQL injection in PHP?
Your code is really escaping the input values but mysql_connect is deprecated in PHP 5.5 and totally dropped in PHP 7.
Using parametric query is your best option:
You need to firstly open connection, instead of
$conn = mysql_connect("localhost", "root", "") or die ('Error connecting to MySQL!');
mysql_select_db("aspire");
You will open connection like this
$mysqli = new mysqli("localhost", "root", "", "aspire");
Then prepare your query, instead of putting query like this
$query = mysql_query("SELECT *, SUM(`times`) as amount FROM votingrecords WHERE account='$account' OR ip='$ip'");
You will put it like this
$stmt = $mysqli->prepare("SELECT *, SUM(`times`) as amount FROM votingrecords WHERE account='?' OR ip='?'");
This one is a prepared statement, it is not you that will put your query input, it is PHP that will do it for you, all you need to do is to bind your query input with that $stmt like this
$stmt->bind_param("s", $account);
$stmt->bind_param("s", $ip);
You are having two inputs which are $account and $ip, the account and ip are both string which happens to be what the s stands for... you will now execute the statement, like this
$stmt->execute();
And don't forget to close connection that you opened
$stmt->close();
see this link
http://php.net/manual/en/pdo.prepared-statements.php
use prepared statements and stored procedures

Getting table doesnt exist with php and mysql

This code down here should search database. but I am getting error that my table doesnt exists. And also I want to ask why if I push second time submit button it just jumps to else so it echo choose at least.... and also all data from database. Thanks!
Here is php
if (isset($_POST['submit'])) {
$query = 'SELECT * FROM station_tab';
if (!empty($_POST['station_name']) && !empty($_POST['city']) && !empty($_POST['zone']))
{
$query .= 'WHERE station_name' .mysql_real_escape_string($_POST['station_name']) . 'AND city' . mysql_real_escape_string($_POST['city']) . 'AND zone' . mysql_real_escape_string($_POST['zone']);
} elseif (!empty($_POST['station_name'])) {
$query .= 'WHERE station_name' . mysql_real_escape_string($_POST['station_name']);
} elseif (!empty($_POST['city'])) {
$query .= 'WHERE city' . mysql_real_escape_string($_POST['city']);
} elseif (!empty($_POST['zone'])) {
$query .= 'WHERE zone' . mysql_real_escape_string($_POST['zone']);
} else {
echo "Choose at least one option for search";
}
$result = mysql_query($query, $db) or die(mysql_error($db));
if (mysql_num_rows($result) > 0) {
while ($row = mysql_fetch_array($result)){
echo '<br/><em>' .$row['station_name'] . '</em>';
echo '<br/>city: '. $row['city'];
echo '<br/> zone: ' .$row['zone'];
echo '<br/> Long: ' .$row['lon'];
echo '<br/> Lat: ' . $row['lat'];
}
}
}
here is error message when I add name of the city to city.
Table 'stanice_tab.station_tabwhere' doesn't exist
Here is your corrected code:
$query = 'SELECT * FROM station_tab '; // note the space at the end
if (!empty($_POST['station_name']) && !empty($_POST['city']) && !empty($_POST['zone'])) {
$query .= ' WHERE station_name = "' .mysql_real_escape_string($_POST['station_name']) . '" AND city = "' . mysql_real_escape_string($_POST['city']) . '" AND zone = "' . mysql_real_escape_string($_POST['zone']).'"'; // note the = signs and the space before each AND
} elseif (!empty($_POST['station_name'])) {
$query .= ' WHERE station_name = "' . mysql_real_escape_string($_POST['station_name']).'"'; // note the = sign and the space at the beginning
} elseif (!empty($_POST['city'])) {
$query .= ' WHERE city = "' . mysql_real_escape_string($_POST['city']).'"'; // note the = sign and the space at the beginning
} elseif (!empty($_POST['zone'])) {
$query .= ' WHERE zone = "' . mysql_real_escape_string($_POST['zone']).'"'; // note the = sign and the space at the beginning
} else {
echo "Choose at least one option for search";
}
Take the habit of echoing your $query variable so concatenation does not add any typo mistakes.
in phpmyadmin select the database and then select your table
and in menu above there is a sql menu. you can use this functionality to construct sql queries or debug when there are errors like this

PHP If Else Not working like i thought it would

Ok i am very stuck here and i am might be looking at this completely wrong (still kind of a newbie) or super close just missing something small i cant tell.
At the bottom here you will find my code with a If ElseIf Else statement. That i just cant get to do what i want. so i am hoping someone can help guide me in the right direction.
On the If it checks to make sure that the promocode that was entered is in the database and that part works.
on the elseif i want it to look through the database and find the promocode and confirm that there isnt an email address associated with that promocode. The way that it is below with the IS NOT NULL in the query works for when there is an email address in that promocode but when there isnt anything for that promocode it is still saying that there is and gives the submit data of today but i can assure that there isnt anything in the database.
This is where my problem lies am i doing this completely wrong is there a better way to accomplish what i am trying to do here? Or have i just overlooked something small?
$promosql = "SELECT * FROM formdata WHERE (promoCode = '$varPromo')";
$promoraw = $mysqli->query($promosql);
$dupesql = "SELECT * FROM formdata WHERE (promoCode = '$varPromo' AND email IS NOT NULL)";
$duperaw = $mysqli->query($dupesql);
if($promoraw->num_rows <> 1) {
//echo ("$varName already exists in $varAddress \n");
$promo .= "$varPromo is not a valid promocode \n";
}
elseif($duperaw->num_rows > 0) {
//echo ("$varName already exists in $varAddress \n");
$dupe .= "$varPromo has already been used on $varDate \n";
}
else {
$sql = "INSERT INTO formdata (promoCode, name, email, address, city, state, zip, submitDate) VALUES (".
PrepSQL($varPromo) . ", " .
PrepSQL($varName) . ", " .
PrepSQL($varEmail) . ", " .
PrepSQL($varAddress) . ", " .
PrepSQL($varCity) . ", " .
PrepSQL($varState) . ", " .
PrepSQL($varZip) . ", " .
PrepSQL($varDate) . ")";
$mysqli->query($sql);
header("location: index.php?success=1");
exit();
}
Try this query:
SELECT email IS NULL or email = '' has_email FROM formdata WHERE promoCode = '$varPromo'
Then your PHP can do:
if ($promoraw->nul_rows == 0) {
// Not a valid promo code
} else {
$row = $promoraw->fetch_assoc();
if ($row['has_email']) {
// Promo code has been used
} else {
// Insert into table
}
}

drop down menu goes back to displaying "Please Select" and fail/success message not appearing

I am having two problems with my code below.
<?php
$validSubmission = isset($_POST['resetpass']) && $_POST['students'] && $_POST['newpass'] && $_POST['confirmpass'];
$sql = "SELECT StudentUsername, StudentForename, StudentSurname FROM Student ORDER BY StudentUsername";
$sqlstmt = $mysqli->prepare($sql);
$sqlstmt->execute();
$sqlstmt->bind_result($dbStudentUsername, $dbStudentForename, $dbStudentSurname);
$students = array(); // easier if you don't use generic names for data
$studentHTML = "";
$studentHTML .= '<select name="students" id="studentsDrop">' . PHP_EOL;
$studentHTML .= '<option value="">Please Select</option>' . PHP_EOL;
$outputstudent = "";
while ($sqlstmt->fetch())
{
$student = $dbStudentUsername;
$firstname = $dbStudentForename;
$surname = $dbStudentSurname;
if (!$validSubmission && isset($_POST['students']) && $student == $_POST['students'])
{
$studentHTML .= "<option value='" . $student . "' selected='selected'>" . $student . " - " . $firstname . " " . $surname . "</option>" . PHP_EOL;
}
else
{
$studentHTML .= "<option value='" . $student . "'>" . $student . " - " . $firstname . " " . $surname . "</option>" . PHP_EOL;
}
}
$studentHTML .= '</select>';
$errormsg = (isset($errormsg)) ? $errormsg : '';
if (isset($_POST['resetpass']))
{
//get the form data
$studentdrop = (isset($_POST['students'])) ? $_POST['students'] : '';
$newpass = (isset($_POST['newpass'])) ? $_POST['newpass'] : '';
$confirmpass = (isset($_POST['confirmpass'])) ? $_POST['confirmpass'] : '';
//make sure all data was entered
if ($studentdrop != "")
{
if ($newpass)
{
if (strlen($newpass) <= 5)
{
$errormsg = "Your Password must be a minimum of 6 characters or more";
}
else
{
if ($confirmpass)
{
if ($newpass === $confirmpass)
{
//Make sure password is correct
$query = "SELECT StudentUsername FROM Student WHERE StudentUsername = ?";
// prepare query
$stmt = $mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("s", $username);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbStudentUsername);
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
if ($numrows == 1)
{
//encrypt new password
$newpassword = md5(md5("93w" . $newpass . "ed0"));
//update the db
$updatesql = "UPDATE Student SET StudentPassword = ? WHERE StudentUsername = ?";
$update = $mysqli->prepare($updatesql);
$update->bind_param("ss", $newpassword, $username);
$update->execute();
//make sure the password is changed
$query = "SELECT StudentUsername, StudentPassword FROM Student WHERE StudentUsername = ? AND StudentPassword = ?";
// prepare query
$stmt = $mysqli->prepare($query);
// You only need to call bind_param once
$stmt->bind_param("ss", $username, $newpassword);
// execute query
$stmt->execute();
// get result and assign variables (prefix with db)
$stmt->bind_result($dbStudentUsername, $dbStudentPassword);
//get number of rows
$stmt->store_result();
$numrows = $stmt->num_rows();
if ($numrows == 1)
{
$errormsg = "<span style='color: green'>Student " . $student . " - " . $firstname . " " . $surname . " has been Registered</span>";
}
else
{
$errormsg = "An error has occured, the Password was not Reset";
}
}
}
else
{
$errormsg = "Your New Password did not Match";
}
}
else
{
$errormsg = "You must Confirm your New Password";
}
}
}
else
{
$errormsg = "You must Enter your New Password";
}
}
else if ($studentdrop == "")
{
$errormsg = "You must Select a Student";
}
}
I am trying to create a rest password page where an admin can reset a student's password.
PROBLEM 1:
In my code what I am trying to do is that if a php validation message appears (one of the $errormsg appears except for the $errormsg which displays the sucess message), then the students drop down menu should still display the option that was selected after the submission of the form occurs. Now this works for all the validation message where the user has left a text input blank, but the only validation message it doesn't work for is when the user has not typed in matching passwords for the new and confirm passwords. If the $errormsg = "Your New Password did not Match";
occurs then the students drop down menu goes back to the Please Select option. How come it goes back to the Please Select option everytime this validation message appears and how can I keep the selected student still selected if this validation occurs?
PROBLEM 2:
If I successfully enter in all the details and submit, it does not perform the insert, yet it does not display the fail message $errormsg = "An error has occured, the Password was not Reset";
or the success message $errormsg = "<span style='color: green'>Student " . $student . " - " . $firstname . " ". $surname . " has been Registered</span>";, why is this occuring? I know the UPDATE statement is correct as I tested this in phpmyadmin.
$username (line 72 and onwards) is never set. I presume this should come from '$studentdrop'?
This means you update where StudentUsername == '', which will fail.
To help you debug:
1. Turn on warning and notices in the error handler for writing code ( error_reporting(E_ALL); ) as it will reveal problems like this
2. As opposed to constantly counting the rows, you can save time in that the bind_result/store_value won't work unless you got a result. So you can check that value you get in bind_result - and if you had checked that `$dbStudentUsername == $username` in line 78, then it would have also thrown a wobbly at that stage.
3. When you've done the "update", you can check the number of "affected rows"; if this > 0 then the password has been updated; no need for a secondary DB query.
Hope that helps

Search for city state zip

So i already have a database of locations of every city, state, zip.
I am currently working on how to do a search and get results of surrounding zip codes x miles away, and have run into some trouble.
I successfully have the search working for you to type in the zip code, since it is a predefined value. But am having trouble with results of a city, state. Currently it only works if you type in just the city name ex "Chicago"... But Does not work if you type in "Chicago, IL".
Here is the code for the $_GET of the search form, searchval
Please Help!
$searchval = $mysql->escape_data($_GET['searchval']);
if (!empty($searchval))
{
if(preg_match("~\d{5}~", $searchval)) {
$zip = $searchval;
}
else {
$city = $searchval;
}
} else
{
$error .= "<div id='Error'>Please enter zip</div>";
$zip = false;
}
Below is the code that actually takes the $zip or $city and gets the surrounding zip codes. if you enter a zip code, it works successfully. If you enter just a city name, it works successfully. If you enter "Chicago, IL" it does not work.
<?php
//if user entered a city ex. "Chicago"
if(isset($city)) {
$q = 'SELECT City, State, ZipCode FROM zipcodes WHERE City like "'. $city .'%" ORDER BY ZipCode ASC Limit 0,10';
$result = $mysql->query($q);
$row = mysqli_fetch_array($result);
$zip = $row[2];
if(mysqli_num_rows($result) != 1) {
echo"Did you mean...<br />";
while($row = mysqli_fetch_array($result)) {
echo "<a href='" .$_SERVER['PHP_SELF'] . "?searchval=".$row[2]."&miles=".$miles."'>" . $row[0] . " " . $row[1] . " " . $row[2] . "</a><br />";
}
}
}
$zcr = new ZipCodesRange($mysql,$zip,$miles);
$zcr->setNewOrigin($zip);
//if user entered a zip code ex. "08026"
if($zcr->validateZipCode($zip)) {
$citystate=$zcr->getCityState($zip);
echo "Zip Codes Within " . $miles ." miles of " . $citystate[0] . ", " . $citystate[1] . " " . $zip;
}
$zcr->setZipCodesInRange();
$zipArray = $zcr->getZipCodesInRange();
asort($zipArray);
$z = implode(",", array_keys($zipArray));
$q = "SELECT * FROM " . TBL_PUBS . " WHERE zip IN ($z) AND( status = 'Pending' OR status = 'Active' )";
$result = $mysql->query($q);
while ($row = $result->fetch_object()) {
$lonlat=$zcr->getLonLat($row->zip);
$distance = $zcr->calculateDistance($lonlat[1], $lonlat[0], $zip);
?>
Was able to solve it using this function...
returns an array of $arr[city] $arr[state] $arr[zip]
function retcszarr($loc){
$usstatenames=array('ALABAMA','ALASKA','AMERICAN SAMOA','ARIZONA','ARKANSAS','CALIFORNIA','COLORADO','CONNECTICUT','DELAWARE','DISTRICT OF COLUMBIA','FEDERATED STATES OF MICRONESIA','FLORIDA','GEORGIA','GUAM','HAWAII','IDAHO','ILLINOIS','INDIANA','IOWA','KANSAS','KENTUCKY','LOUISIANA','MAINE','MARSHALL ISLANDS','MARYLAND','MASSACHUSETTS','MICHIGAN','MINNESOTA','MISSISSIPPI','MISSOURI','MONTANA','NEBRASKA','NEVADA','NEW HAMPSHIRE','NEW JERSEY','NEW MEXICO','NEW YORK','NORTH CAROLINA','NORTH DAKOTA','NORTHERN MARIANA ISLANDS','OHIO','OKLAHOMA','OREGON','PALAU','PENNSYLVANIA','PUERTO RICO','RHODE ISLAND','SOUTH CAROLINA','SOUTH DAKOTA','TENNESSEE','TEXAS','UTAH','VERMONT','VIRGIN ISLANDS','VIRGINIA','WASHINGTON','WEST VIRGINIA','WISCONSIN','WYOMING');
$usstateabbrs=array('AL','AK','AS','AZ','AR','CA','CO','CT','DE','DC','FM','FL','GA','GU','HI','ID','IL','IN','IA','KS','KY','LA','ME','MH','MD','MA','MI','MN','MS','MO','MT','NE','NV','NH','NJ','NM','NY','NC','ND','MP','OH','OK','OR','PW','PA','PR','RI','SC','SD','TN','TX','UT','VT','VI','VA','WA','WV','WI','WY');
if(strpos($loc,',')!==false){
$parts=array_map('trim',explode(',',$loc));
$location['city']=strtoupper($parts[0]);
preg_match('/([^ ]*)(?: +([^ ]+))?/',$parts[1],$statezip);
if(isset($statezip[1])){
$location['state']=strtoupper($statezip[1]);
}
if(isset($statezip[2])){
$location['zip']=$statezip[2];
}
} else {
$parts=array_map('trim',explode(' ',$loc));
while(count($parts)>0){
$part=strtoupper(array_pop($parts));
if(in_array($part,$usstateabbrs)){
$location['state']=$part;
} elseif (in_array($part,$usstatenames)){
$location['state']=$usstateabbrs[array_search($part,$usstatenames)];
} elseif (preg_match('/\d+(?:-\d+)?/',$part,$zip)){
$location['zip']=$zip[0];
} else {
$location['city']=strtoupper(implode(' ',$parts)."$part");
break;
}
}
}
ksort($location);
return $location;
}

Categories