Row is inserted into database everytime I refresh the page - php

Every time I try to refresh the page I get a new row. I tried to read many posts regarding to this problem, but I couldn't do anything since I'm new in database programming.
I don't know where the value come from, because the same value is repeated over and over.
My code.
<?php
require('connect.php');
$sql="CREATE TABLE test(id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
user VARCHAR(25),message LONGTEXT)";
if($sql==true){
$res=mysql_query( $sql);
}
?>
<?php
$user=null;
$message=null;
if(isset($_POST['user'])){
$user=$_POST['user'];
}
if(isset($_POST['message'])){
$message=$_POST['message'];
}
if(!empty($_POST)){
if($user&&$message){
$insert=mysql_query("INSERT INTO test(user,message)VALUES('$user','$message')");
}
else{
echo "please fill out the fields";
}
}
?>
<html>
<body>
<form action="database.php" method="post">
<p><label for="user">Name:</label><br/>
<input type="text" name="user" id="user"/></p>
<p><label for="message">Message:</label><br/>
<textarea ="message" name="message"> </textarea></p>
<button type="submit" name="submit" value="send">Send Message:</button>
</form>
<br/><br/><tr><td>The Users Comments:</td><td><br/><br/>
</html>
<?php
$query=mysql_query("SELECT * FROM test ORDER BY id DESC");
while($row=mysql_fetch_ASSOC($query)){
$name=$row["user"];
$message=$row["message"];
echo "username:",$name,'<br/>'," Messages: ",$message,'<br/>','<br/>';
}
?>

Problem is that everytime you refresh the page your browser is re-posting the same data. To workaround it you should consider implementing the Post, Redirect, Get pattern in your page.
Fundamentally this means that upon a successful POST (i.e. row was inserted) you should redirect to another page. This effectively stops the user from having the ability to re-post the same data.
The link above has a good overview of how to implement...

I don't find a problem in your code. Probably when you post data first time and then refresh the page, data is posted again. Most of the browsers like firefox gets confirmation if browser is re-posting data.
Edit:
To avoid this you must use redirect to GET method. see this

try to edit this
Blockquote
if(!isset($_POST)){
if($user && $message){
$insert=mysql_query("INSERT INTO test(user,message)VALUES($user,$message)");
}
and be sure ctrl+f5 then refresh page

Before insert check database if those values are present in database or not
like
if(!empty($_POST)) {
if($user && $message) {
//check if this user and message in present database or not
$query = mysql_query("SELECT * FROM test WHERE user='".$user."' AND message='".$message."'");
$count = mysql_num_rows($query);
if ($count > 0 ){ // if $count is greater than 0 means values exists in database then
echo "Data exists";
}
else {
// insert
$insert=mysql_query("INSERT INTO test(user, message) VALUES ('$user','$message')");
}
}
else {
echo "please fill out the fields";
}
it is just a example you can modified it with your requirement :)

Related

Checking to see if email is in database after hitting submit then going to url php

I'm setting up a RSVP type form on a wordpress page. Everything is sortof working but would like to fine tune things. Since I'm kindof new to PHP I thought I would ask some experts. I'm coming up with two problems.
1) When the page displays it starts checking for the email automatically before hitting submit. Is there a way to show nothing before hitting submit. Right now it is displaying the echo for the else.
When hitting submit the only way I was able to get the page to go to another url was through refresh. I couldn't get the header function to work it just kept going to a blank page.
I appreciate all the help. Here is my code.
<?PHP
if($_POST['email'] != ''){
// the email to validate
$email = $_POST['email'];
$query = mysql_query("SELECT * FROM tablename WHERE rsvpemails='$email'");
}
if(mysql_num_rows($query) != 0) {
echo '<div class="good"><h2>Your email is approved</h2>RSVP please continue to the RSVP form</div>';
echo '<META HTTP-EQUIV="Refresh" Content="0; URL=url">';
exit;
}
else {
echo '<div class="bad">Please enter your email address we used for the invite. If you have any questions or problems please email us at none#none.com</div> ';
}
?>
<form method="POST">
<input type="text" name="email">
<input type="button" value="submit">
</form>
One thing to note is that your SQL query is vulnerable to SQL Injection.
https://en.wikipedia.org/wiki/SQL_injection
You should be sanitizing your POST variables, like ->
$email = mysql_real_escape_string($_POST['email']);
To your actual question, however -
Move your if(mysql_num_rows($query) != 0) block into the if($_POST['email'] != '') block so that it only checks for row data if $_POST['email'] is set (and consequently $query will be populated with something).
Here's also some more info on meta refresh tags.
https://en.wikipedia.org/wiki/Meta_refresh
Put entire PHP code in condition.
<?php
if($_POST['email'] != ''){
// the email to validate
$email = $_POST['email'];
$query = mysql_query("SELECT * FROM tablename WHERE rsvpemails='$email'");
if(mysql_num_rows($query) != 0) {
header("location: $url"); // Redirect
exit;
}
else {
echo '<div class="bad">Please enter your email address we used for the invite. If you have any questions or problems please email us at none#none.com</div> ';
}
}
?>
You need to check if a form was submitted, BEFORE you start doing the verification:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
... form was submitted, validate it
}
You're running your query only if something was submitted, but checking the database result regardless. So if nothing gets submitted, you STILL check the number of rows returned, which is obviously zero, since you never ran the query in the first place.

How to restrict update or insert more than once by navigating back to referring page in php?

I am developing a web application where I want to restrict update or insert more than once by navigating back to referring page. Let me present you three model files in the order of flow so that I can raise the zone where I am stuck.
register.html
<html>
...
<form id="form1" name="form1" method="post" action="process.php">
<label for="textfield">Name</label>
<input type="text" name="name" id="name" />
<input type="submit" name="Submit" value="Submit" />
</form>
...
</html>
process.php
<?php
echo "Welcome ".$_GET['para'];
?>
success.php
<?php
if(isset($_POST['Submit']))
{
$name = $_POST['name'];
// some database update here ...
echo "<a href='success.php?para=$name'>Done. Click to go next</a>";
unset($_POST['Submit']);
}else{
echo "Error in submission";
}
?>
The above three files are very simple. Here the update part has nothing to do when the user hits the back button after landing on page success.php because of unset($_POST['Submit']);. But when the user goes back further by hitting the back button again it reaches register.html and can again come up with the $_POST['Submit'] set and may do the update part which is sometimes vulnerable. I know there is Post/Redirect/Get to solve this issue, but I want some other alternatives so that the part gatekeepering the update part may be made so efficient that it would not allow the same anymore by clicking the back button.
If you are getting duplicate records inserted.
You may try INSERT IGNORE
ADD UNIQUE INDEX to your table to prevent this happening
you may choose any one of INSERT IGNORE and REPLACE according to the duplicate-handling behavior
Refer https://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
Lastly you may like simple php with mysqli_num_rows()
$sql = "SELECT id FROM table-name WHERE column-name1 = ? AND column-name2 = ? ;
$mq = mysqli_query($sql);
if (mysqli_num_rows($mq) < 1) {
$sql = "UPDATE table-name SET (colum-names) VALUES (...)";
mysqli_query($sql);
else {
echo "Record already updated";
}
}

Saying wrong details but I'm typing it correctly - PHP

I'm trying to make login system by a tutorial. I'm making everything like in tutorial but it says my details are incorrect and it wont log me in but everything is correct. I can't find is there anywhere mistake in code or something. Any help is welcome!
Index.php code:
<?php #admin/index.php
#####[make sure you put this code before any html output]#####
//connect to server
$dbc = mysqli_connect('localhost','root','pw') or
die('could not connect: '. mysqli_connect_error());
//select db
mysqli_select_db($dbc, 'dbname') or die('no db connection');
//check if the login form has been submitted
if(isset($_POST['go'])){
#####form submitted, check data...#####
//step 1a: sanitise and store data into vars (storing encrypted password)
$usr = mysqli_real_escape_string($dbc, htmlentities($_POST['u_name']));
$psw = SHA1($_POST['u_pass']) ; //using SHA1() to encrypt passwords
//step2: create query to check if username and password match
$q = "SELECT * FROM kasutaja WHERE name='$usr' AND pass='$psw' ";
//step3: run the query and store result
$res = mysqli_query($dbc, $q);
//make sure we have a positive result
if(mysqli_num_rows($res) == 1){
######### LOGGING IN ##########
//starting a session
session_start();
//creating a log SESSION VARIABLE that will persist through pages
$_SESSION['log'] = 'in';
//redirecting to restricted page
header('location:restricted.php');
} else {
//create an error message
$error = 'Wrong details. Please try again';
}
}//end isset go
?>
<!-- HTML FORM GOES HERE -->
<!-- LOGIN FORM in: admin/index.php -->
<form method="post" action="#">
<p><label for="u_name">username:</label></p>
<p><input type="text" name="u_name" value=""></p>
<p><label for="u_pass">password:</label></p>
<p><input type="password" name="u_pass" value=""></p>
<p><button type="submit" name="go">log me in</button></p>
</form>
<!-- A paragraph to display eventual errors -->
<p><strong><?php if(isset($error)){echo $error;} ?></strong></p>
Restricted page code:
<?php #admin/restricted.php
#####[make sure you put this code before any html output]#####
//starting the session
session_start();
//checking if a log SESSION VARIABLE has been set
if( !isset($_SESSION['log']) || ($_SESSION['log'] != 'in') ){
//if the user is not allowed, display a message and a link to go back to login page
echo "You are not allowed. back to login page";
//then abort the script
exit();
}
/**
* #### CODE FOR LOG OUT #### click here to see the logout tutorial
*/
?>
<!-- RESTRICTED PAGE HTML GOES HERE -->
<h1> TEST </h1>
Thanks for helping!
This is a fix for http://www.cramerz.com/php/php_login_system which contains errors that the OP downloaded from the Web. No wonder the OP had a hard time.
It queries the wrong columns for one thing and inserts into the wrong table.
Another error with their code is this line:
echo "You are not allowed. back to login page";
which would throw an error and should read as, and escaping the quotes for index.php
echo "You are not allowed. back to login page";
Rewrite
Most of the Websites have a sort of private section where normal users are not allowed. You can think about an ADMIN section where the webmaster finds his CMS, a private area with sensitive personal information or even just the email manager you use to handle your emails.
All of these cases have something in common: they restrict access to allowed users only, with a login system.
To create an authentication system you will need:
A database, a table called users with at least three columns: id, username, password
A HTML form where users fill in their usernames and passwords
A PHP script that will check if usernames and passwords provided actually exist
A private area users can access only if successfully logged in
STEP 1. create a table called users:
a) Use PhpMyAdmin or any other GUI to quickly create a table
CREATE TABLE `users` (
`id` INT( 5 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`username` VARCHAR( 50 ) NOT NULL ,
`password` VARCHAR( 50 ) NOT NULL
)
b) Insert a couple of users:
INSERT INTO `users`
( `id` , `username` , `password` )
VALUES ( NULL , 'john', SHA1('johnPsw' ) ),
( NULL , 'james', SHA1('jamesPsw') ),
( NULL , 'jim', SHA1('jimPsw' ) );
PLEASE NOTE: we are using the SHA1() function to encrypt passwords.
STEP 2. login form:
<!-- LOGIN FORM in: admin/index.php -->
<form method="post" action="">
<p><label for="u_name">username:</label></p>
<p><input type="text" name="u_name" value=""></p>
<p><label for="u_pass">password:</label></p>
<p><input type="password" name="u_pass" value=""></p>
<p><button type="submit" name="go">log me in</button></p>
</form>
<!-- A paragraph to display eventual errors -->
<p><strong><?php if(isset($error)){echo $error;} ?></strong></p>
STEP 3. php script:
<?php #admin/index.php
#####[make sure you put this code before any html output]#####
//connect to server
$dbc = mysqli_connect('localhost','root','') or
die('could not connect: '. mysqli_connect_error());
//select db
mysqli_select_db($dbc, 'examples') or die('no db connection');
//check if the login form has been submitted
if(isset($_POST['go'])){
#####form submitted, check data...#####
//step 1a: sanitise and store data into vars (storing encrypted password)
$usr = mysqli_real_escape_string($dbc, htmlentities($_POST['u_name']));
$psw = SHA1($_POST['u_pass']) ; //using SHA1() to encrypt passwords
//step2: create query to check if username and password match
$q = "SELECT * FROM users WHERE username='$usr' AND password='$psw' ";
//step3: run the query and store result
$res = mysqli_query($dbc, $q);
//make sure we have a positive result
if(mysqli_num_rows($res) == 1){
######### LOGGING IN ##########
//starting a session
session_start();
//creating a log SESSION VARIABLE that will persist through pages
$_SESSION['log'] = 'in';
//redirecting to restricted page
header('location:restricted.php');
} else {
//create an error message
$error = 'Wrong details. Please try again';
}
}//end isset go
?>
<!-- HTML FORM GOES HERE -->
STEP 4. restricted page:
<?php #admin/restricted.php
#####[make sure you put this code before any html output]#####
//starting the session
session_start();
//checking if a log SESSION VARIABLE has been set
if( !isset($_SESSION['log']) || ($_SESSION['log'] != 'in') ){
//if the user is not allowed, display a message and a link to go back to login page
echo "You are not allowed. back to login page";
//then abort the script
exit();
}
else{
echo "Success!";
}
/**
* #### CODE FOR LOG OUT #### click here to see the logout tutorial
*/
?>
<!-- RESTRICTED PAGE HTML GOES HERE -->

Empty rows created by refreshing page

I've searched on the Internet to get my answer, but I couldn't find a helpful one. I've got a page called 'post.php' with a form where I can add an image and submit it to the database.
The big problem is when I go to mysite.com/post.php a new empty row is created automatically in the database, which I clearly don't want. I want only to update the database after clicking on the submit button my code:
the part of INSERT:
<?php
// POST.PHP POSTING NEW CONTENT
include 'config.php';
// values from form
$id=$_POST['id'];
$title=$_POST['title'];
$pic=$_POST['pic'];
$youtube=$_POST['youtube'];
$cat=$_POST['cat'];
// insert data to mysql
$sql = "INSERT INTO post(id, title, pic, youtube, cat)VALUES('$id', '$title', '$pic', '$youtube', '$cat')";
$result=mysql_query($sql);
// succes added
if(!$result){
echo "Something went wrong!";
}
else {
echo "Yeah, buddy! Your content is added.";
}
// end of post script ^^
?>
// end of insert
//POST IMAGE PAGE
if(isset($_GET['pic'])) {
?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
title: <input name="title" type="text" id="title"><br />
Add url of image;<br />
<input type="text" name="pic" id="pic"/><br />
<?php
echo '
Category game:
<select name="cat"> ';
$query2 = mysql_query("SELECT * FROM `category`");
while($row=mysql_fetch_array($query2)){
echo '
<option value="'.$row["nameID"].'">'.$row["name"].'</option> ';
}
?>
</select>
<input type="submit" onclick="this.disabled = true" name="submit" value="submit">
</form>
<?php
// end script of posting picture
}
?>
You need to add some conditional code around the part that inserts into the database, checking for if any values has been received (if($myvar){ // do stuff }).
Add the rest of your code, specifically the part that adds stuff to the database as that is what's causing you problems, not the code you posted.
You need to wrap the whole block of database insertion code in an if statement. That way, it will not execute until the form has been submitted and $_POST['submit'] has a value:
include 'config.php';
if (isset($_POST['submit'])){
// values from form
$id=$_POST['id'];
// etc... code stays the same down to:
echo "Yeah, buddy! Your content is added.";
}
}//end if (don't forget to add this last bracket)
Also, you should switch to mysqli or PDO, and use parameterized queries. Otherwise, your site is open to a variety of gnarly attacks via SQL injection. It's not that hard to switch, and very, very important.
Check if the post have been set on the file that handles the database input.
if(isset($_POST['pic'])){
//do something
}
else{ // handle the exeption}
Also, you should not use mysql_* functions anymore. they are unsafe and deprecated as-of php 5.5

Prevent Double Form Submit using Tokens

I am trying to prevent the user from double submitting the forum by adding token hidden field.
So here is what I have done so far (before the forum loads I have this code to create a token with the current time as a value.
$token = time();
setcookie('formToken', $token, time() + 3600);
in my forum I have a hidden input like this
<form method="post" action="'.$PHP_SELF.'?action=update">
<input type="hidden" name="token" value="'.$token.'" />
<input type="submit" value="go" />
</form>
now on the top of my page where $action == "update" I have this code
if(isset($_POST) && ($_POST['token'] != $_COOKIE['formToken'])){
$error_list .= '<li>You can not submit this forum twise.</li>';
}
if i hit F5 to refresh the page it submit the form again without displaying my error.
I suggest you to use use the PRG pattern (Post/Redirect/Get), which is also implemented by forums like phpbb.
Post/Redirect/Get (PRG) is a web development design pattern that
prevents some duplicate form submissions, creating a more intuitive
interface for user agents (users). PRG implements bookmarks and the
refresh button in a predictable way that does not create duplicate
form submissions.
gd1 answer will not prevent double click submission or accidental double submit by various jQuery bindings on a complex javascript form code.
Double click may be even faster then disabling submit button, or hiding it with javascript, so this would not be a full answer either.
The session token will not work either because session is not yet written and thus available or updated for the second process which may be just milliseconds away sharing the same session ID. The session is stored only upon completion of the fist process.
Cookie technique could be an answer as far as both processes are able to communicate over cookie in a blocking way, which may result to the same problems as the session sharing above.
The best solution would be to use server's shared memory access to check if the other process had already processed the data (order, payment, etc..) with the pregenerated data hash, or use database table blocking select and insert to check if the pregenerated hash has been already submitted.
Why not just set a session when the form is successfully submitted?
so $_SESSION['submitted'] = 1;
Then you can check for it.
Or Do
if(isset($_POST['submit']) && ($_POST['token'] != $_COOKIE['formToken'])){
$error_list .= '<li>You can not submit this forum twice.</li>';
}
Suggestion 1)
on Successful Submission Delete the cookies (removeTokens)
function removeToken()
{
//set formToken cookie val to "" (or any default xxxx) and the past expiry date for it
setcookie("formToken", "", time()-3600);
//try to unset - this is not needed ,we may try it
unset($_COOKIE['formToken']);
}
ie simply on your page if(isset($_POST)) removeToken();
Suggestion 2)
Perform a redirect as suggested by Tom Wright here Avoiding form resubmit in php when pressing f5
header('Location: formsubmitSucess.php');
I use this way of preventing double form submissions, it has worked on all occasions so far. Let me know if you need additional questions as this tutorial assumes you have intermediate knowledge on database and PHP.
STEP 1 : add a field on your database like this:
replace YOUR-TABLE with the name of your database table.
ALTER TABLE `YOUR-TABLE` ADD `token` VARCHAR(35) NULL DEFAULT NULL AFTER `creationtoken`, ADD UNIQUE (`token`) ;
STEP 2 on your form page you add this to the very first line:
it will create a unique toke that will be inserted into your database table along with you query, so that it can be checked for later to make sure no other like it is submitted into your database, meaning no double form submissions.
<?php
session_start();
date_default_timezone_set('America/Chicago');
$_SESSION['token'] = md5(session_id() . time());
?>
then just before your submit button add this:
// add this before the submit button
// this will post the unique token to the processing page.
<div style="width:100%; color:#C00; font-weight:normal;">Session Token: <?php echo strtolower($_SESSION['token']) ?></div>
<input type="hidden" name="token" id="token" value="<?php echo $_SESSION['token']?>" />
// add this before the submit button
<input type="submit" id="submit" name="submit" class="button" value="Submit" />
STEP 3: now on your process.php page
//this is where all of your form processing takes place.
// this is where you call the database
// if you need the database file let me know...
include("../common/databaseclass.php");
$db= new database();
//here the token is posted then the database table is checked and
//if the form has already been added it will return a 1 and will
//cause the query to die and echo the error message.
$token = $_POST['token'];
$query = "SELECT token FROM YOURTABLE WHERE token = '$token' LIMIT 1";
$result = $db->query($query);
$num = mysql_num_rows($result);
if ($num>0) {die('your form has already been submitted, thank you');}
else {
$host = "localhost";
$user = "user";
$pass = "password";
$db_name = "database";
mysql_connect($host,$user,$pass);
#mysql_select_db($db_name) or die( "Unable to select database");
// table query
$sql1="INSERT INTO YOURTABLE (
`token`,
`user`,
`email`,
`password`,
`newaccount`,
`zipcode`,
`city`,
`state`,
`country`,
`telephone`,
`creationip`,
`createdaccount`
)
VALUES (
'$token',
'$username',
'$email',
'$password',
'$newaccount',
'$zipcode',
'$city',
'$state',
'$country',
'$phone',
'$ipadress',
'$createdaccount'
)";
$db->query($sql1);
header("location:" http://home.php ");
}
For the same issue I made a code to use it for my own stuff. It has the PRG pattern and flexible to use it on same page or with extern PHP file for redirection - Easy to use and safe, maybe this might help you.
class unPOSTer {
private
$post = "KEEP_POST";
public function __construct(string $name = null) {
if (version_compare(PHP_VERSION, "5.4.0") >= 0) {
if (session_status() == PHP_SESSION_NONE) {
session_start();
}
} else {
if (!$_SESSION) {
session_start();
}
}
$this->post = $name;
}
public function unPost() {
if (session_status() !== PHP_SESSION_ACTIVE) {
session_start();
} elseif (strcasecmp($_SERVER["REQUEST_METHOD"],"POST") === 0) {
$_SESSION[$this->post] = $_POST;
header("Location: " . $_SERVER["PHP_SELF"] . "?" . $_SERVER["QUERY_STRING"]);
exit;
} elseif (isset($_SESSION[$this->post])) {
$_POST = $_SESSION[$this->post];
}
}
public function retrieve($data) {
if (isset($_SESSION[$this->post])) {
$posts = #$_SESSION[$this->post][$data];
if (isset($posts)) {
return $posts;
} else {
return null;
}
}
}
public function reset() {
if (isset($_SESSION[$this->post])) {
unset($_SESSION[$this->post]);
}
}
}
Then use it like this:
<?php
require_once "unPOSTer.class.php";
$unpost = new unPOSTer();
$unpost->unPost();
?>
<form action='' method=POST>
<input type=text name=fname value="<?php echo $unpost->retrieve("fname"); ?>" placeholder="First Name">
<input type=text name=lname value="<?php echo $unpost->retrieve("lname"); ?>" placeholder="Last Name">
<input type=submit name=send value=Send>
</form>
<?php echo $unpost->reset(); ?>
Not much to configure, do it on every page you send form data if you like. The retrieve() method spits out the data you have sent, in case if you might go back and fix something. Feel free to fork/pull it at my GitHub page I added 2 demos there.
I had the same problem, here is a simple fix:
if(!empty($_SESSION['form_token']) && time() - $_SESSION['form_token'] < 3){
$data['message'] = 'try again later';
return;
}
$_SESSION['form_token'] = time();
In my case the PRG pattern didn't have any effect since form submitted multiple times at the same time and the code had not been executed and there is no data saved to compare it against.

Categories