I have searched many posts here and elsewhere but can't seem to find a solution to my problem.
I have a page which displays database entries: database.php. These entries can be filtered with a form. When I filter them and only display the ones I am interested in I can click an entry (as a link) which takes me to that entries page (via php GET). When I am on that entries page (i.e., "view.php?id=1") and hit the back button (back to database.php), the filter form requires to confirm the form resubmission. Is there any way to prevent this?
here are some (simplified) code examples:
Database.php:
<form>
<select>
<option>1</option>
<option>2
<option>
</select>
<input type="submit" name="apply_filter" />
</form>
<?php
if ( isset( $_POST[ "apply_filter" ] ) ) { // display filtered entries
$filter = $_POST[ "filter" ];
$q = "Select * from table where col = '" . $filter . "'";
$r = mysql_query( $q );
} else { // display all entries
$q = "Select * from table";
$r = mysql_query( $q );
}
while ( $rec = mysql_fetch_assoc( $r ) ) {
echo "<a href='view.php?id=" . $rec[ "id" ] . "'>" . $rec[ "name" ] . "</a><br />"; // this is where the link to the view.php page is...
}
?>
Now as mentioned, if I click on the link, it takes me to "view.php?id=whatever". On that page, I just get the ID from the url to display that single entry:
view.php:
<?php
$id = $_GET[ "id" ];
$q = "Select * from table where id = '" . $id . "'";
$r = mysql_query( $q );
while ( ) {
// display entry
}
?>
If I now hit the back button, the form on database.php (the one used to filter the DB results) requires confirmation for resubmission. Not only is this very annoying, its also useless to me.
How can I fix this? I hope the code examples and explanation of my problem are sufficient. If not let me know and I'll try to specify.
I know this question is old, but having this issue myself, two lines I've discovered that works are:
header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
There are two ways I know of to do this. The simple way and the hard way.
Regardless of the way, when you are dealing with a state-based page (using $_SESSION), which you should be doing to keep your pages "live" and under your control, is prevent the caching of all pages like this:
<?php
//Set no caching
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
?>
The hard way involves generating an id and storing it somewhere on the page as a hidden input or a &_SESSION cookie. Then you store the same id on the server as a $_SESSION. If they don't match, a series of preprogrammed if else type statements cause nothing to happen with the page is resubmitted (which is what it tries to do when you click back).
The easy way is to simply redirect the user back to the form submission page if the form was submitted successfully, like so:
header('Location: http://www.mydomain.com/redirect.php');
I hope this helps!
One thing that might help is making your filter form use a GET method instead of POST.
Browsers usually prevent POST input from being automatically resubmitted, which is something they don't do when GET input is used. Also, this will let users link to your page using a filter.
header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
NOTE: After using the post data what you have submitted from the form then, these two lines should be used at the end of function.so, when we are back to the redirected page, it will not ask you to resubmit the page. This will work.
I used the answer at How do I detect if a user has got to a page using the back button? to detect whether or not the visit was triggered by a browser's back button click, and then if that was the case, I used JavaScript to reload the page. When the page is reloaded, my code already handles the corresponding validations to make sure that the form is never submitted twice. The important part in my case was forcing the page reload when the form was revisited after clicking the browser's back button. This is my code in the URL where I wanted to apply this validation:
<script type="text/javascript">
if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
location.reload();
}
</script>
An alternative solution that also works if/when the page is reloaded involves checking the post's originality using $_SESSION. In a nutshell, check for a unique or random string.
In the form, add an input element with a value set using rand() or microtime():
<input type="hidden" name="formToken" value="<?php echo microtime();?>"/>
And then wrap the PHP function to validate and parse the form data in an if block:
if(!isset($_SESSION['formToken']) || $_POST['formToken'] !== $_SESSION['formToken'])){
$_SESSION['formToken'] = $_POST['formToken'];
/*continue form processing */
}
The solution the works for me is
$(document).ready( function() {
//prevent form submit on refresh or resubmit with back button
if ( window.history.replaceState ) window.history.replaceState( null, null, window.location.href );
}
Its already mentioned above but again i will say it, if you have used session_start() in your code then you just need to add this line in your header file like:-
<?php
header("Cache-Control: no cache");
?>
but if you didnt have used yet the session_start() then you can add the line below in your header file like:-
<?php
header("Cache-Control: no cache");
session_cache_limiter("private_no_expire");
?>
The following worked for me when I add this code to the end of my script after the submission/redirection
unset($_POST);
exit();
So simple but it took way too long for me to figure it out.
You need to remove the request which POST data from browser history
history.replaceState("", "", "/the/result/page")
See this answer
Also you may follow the Post/Redirect/Get pattern.
Related
I wrote the following code to delete entries on my SQL table:
echo "<td><a href='protected_page.php?action=delete&id=$id'>Borrar</a></td>";
}
if(($_GET['action'] == 'delete') && isset($_GET['id'])) {
$rem = "DELETE FROM busca WHERE id = '".$_GET['id']."'";
$mysqli->query($rem);
if($rem) {
echo "<meta http-equiv='refresh' content='0;URL=/protected_page.php'>";
}
}
Once I click the delete link the page enters into an infinite loop.
Look at your attribute value:
content='0;URL='/protected_page.php''
You are delimiting the value with ' but trying to use ' characters as data inside it.
This isn't possible so what you are really saying is:
content='0;URL='
The correct syntax is:
<meta http-equiv='refresh' content='0;URL=/protected_page.php'>
… without the quotes around the URL portion.
That said, meta refresh is a nasty approach to performing a redirect. An HTTP redirect is better:
<?php header("Location: /protected_page.php"); ?>
You will need to adjust your logic a little. HTTP headers have to be output before the HTTP body, and you're doing your delete & redirect logic in the middle of your HTML output.
As a rule of thumb it is better to put all your business logic (deleting things, fetching data from the database, etc) at the top of your PHP program, and then leave all the business of generating HTML and other output (using variables you populated in the business logic part at the top) at the bottom.
If you really want to use PHP for this, here you go:
//0 = is second after is refresh
<?php header("Refresh: 0; URL=http://redirect-url"); ?>
If You Want Use HTML for This, Here you Go
//0 = is second after is refresh
<meta http-equiv="refresh" content="0;http://redirect-url" />
use header instead of meta tag as below
if($rem) {
header( 'Location: protected_page.php' );
}
Hi I wrote a javascript click count its working properly but i want it to pass a single click to an external php script so as to insert the click and the id into db, it redirect a person to deals.php once a click is made on "click me" href and counts ,this is my code: Any help would be appreciated.
<script type="text/javascript">
var clicks = 0;
function linkClick()
{
document.getElementById('234').value = ++clicks;
}
document.write('<a href="deals.php?name=" + ++clicks;
onclick="linkClick()">Click Me!</a>');
</script>
You have clicked the link times.enter code here
You Can done it by using php only
on HTML Page
<?php
$query=mysql_query("select clickCount from click_count");
$result=mysql_fetch_assoc($query);
$clickCount=result['clickCount '] // get the value from database ?>
<a href="deal.php?name=<?php echo ($clickCount+1);?>" >click me</a>
on deal.php Page
let table name is click_count
$clickCount=$_GET['name'];
mysql_query("update click_count set clickCount = '".$clickCount."'");
You should not relay on client side to count the clicks. This should be done in PHP when the user clicks:
Click me
and then, on deal.php:
$id = $_GET['id'];
$clicksCount = getClicksCountForId($id);
setClicksCountForId($id, $clicksCount++);
get and set clicks count into database can be done like Shut proposed in his answer.
It's possible to simplify your code by doing everything on the PHP side and storing the clicks counter in $_SESSION. The first time it's going to be zero ($_SESSION["clicks"] = 0;), when user clicks the link, "deals.php" will be executed, and the value will be increased (and database updated), example :
main.php
<?php
session_start();
if ( ! isset( $_SESSION[ "clicks" ] ) ) // FIRST TIME.
$_SESSION[ "clicks" ] = 0;
?>
<html>
<body>
Click Me!
<input type="text" value="<?php echo $_SESSION['clicks'];?>"/>
</body>
</html>
deals.php
<?php
session_start();
$_SESSION[ "clicks" ]++; // INCREASE COUNTER.
// <=== UPDATE DATABASE HERE.
header( "Location: main.php" ); // RETURN TO MAIN.PHP.
?>
If you create two files with the given names (main.php, deals.php) and paste previous codes, it will work like you want : every click will be stored in database.
I got a code here that if I refreshed the page it automaticaly save the data....can anyone help me that it will only save if the submit button is clicked.
current code:
<?php
ob_start();
?>
<html>
<head>
<title>test</title>
</head>
<body>
<?php
include('include/connect.php');
$query = mysql_query("SELECT DISTINCT count(batchcode) as batchcode1 FROM batchcodes");
while( $rows = mysql_fetch_array($query)) {
$code=$rows['batchcode1'];
}
if(isset($_POST['save'])){
$var = $code+1;
$sql = mysql_query("INSERT INTO batchcodes(batchcode) VALUES (". $var .")");
}
?>
<form method="post" action="index.php" >
<input type="text" value="batch<?php echo $var; ?>" />
<input type="submit" name="save">
</form>
</body>
</html>
The code you show is from your "handling" page. That page handles the post, it checks if there was a parameter "save" and if so, it saves.
If the user refreshes that page, he visits the page again, sending again a "save" parameter, so the INSERT is done twice.
To avoid this, you should use the POST-REDIRECT-GET model, where your handling page gets the data, saves it, and then redirects the user to a "GET" page (no post, no insert) that just shows the data. If the user then hits refresh, he only refreshes the "GET" page.
Offcourse, a user can always keep using the BACK button to go to the actual insert page. His browser will warn him "you are resubmitting form data...", but if he chooses to, he can. If you really want to handle this, you can work with session keys: have an extra field "submitID" on your form, and on INSERT, first check if that ID was already "used". You'll need an extra table/column "submitID" somewhere to ensure a form can only be submitted once.
The problem is the form is getting submitted again, you can make header redirect to this same page,
header("location: index.php) after updating your database and this will solve your issue.
Create one button in html
<input type="submit" name="submit"/>
In php Code, you can write like
<?php
if(isset($_POST['submit']))
{
//place your total code here
}
?>
As soon as the form is submitted once it has got the $_POST-Array in the site request. When you reload the page after the first submit, it will always send the data again.
You got multiple possibilities to resolve this problem:
1)
Reload the page after the execution of the PHP code. To do so put the PHP code at the top of the page (before writing anything in HTML) and reload the page after the execution of the query:
if(isset($_POST["save"])) {
/* MySQL Query */
$back = $_SERVER['HTTP_REFERER'] ; // the site who called this site
header("Location: $back") ; // Link back to this site
}
2)
Personally I prefer to execute my PHP scripts with an Ajax call, which would look as follows in jQuery.
function ajaxCall()
{
$.ajax({
type: "POST",
url: "handler.php",
data: {save: 1, textfield: $("#textfield").val()}
}) ;
}
Don't forget, that the forms action isn't the redirect to another site anymore, it is the call to this function ajaxCall. If you want more fields to submit, have a look at the serialize-function. The handler.php-file contains only your php-Code:
<?php
ob_start();
include('include/connect.php');
$query = mysql_query("SELECT DISTINCT count(batchcode) as batchcode1 FROM batchcodes");
while( $rows = mysql_fetch_array($query)) {
$code=$rows['batchcode1'];
}
if(isset($_POST['save'])){
$var = $code+1;
$sql = mysql_query("INSERT INTO batchcodes(batchcode) VALUES (". $var .")");
}
exit(0) ;
?>
In the ajax function you could also handle what happens when the call is successful (e.g. redirect). Have a look at the $.ajax-reference of jQuery. If you want you could also use ajax without jQuery.
3)
You could also make your page in action similiar to the handler.php in the second possibility.
<form action="handler.php" method="POST"></form>
In this case you had to replace the exit-statement with the $back and header-call in possibility 1 (similar to the response of Konerak).
I'm setting a cookie on one page and trying to unset on the next page, which I reach via a link. However, the cookie only gets unset when I refresh the second page, F5.
For testing, I have the link and some cookie setting on the first page like this:
<?php
include("connect-db.php");
$id = "newuser";
setcookie("user_id", $id, time() + 31536000);
if (isset($_COOKIE["user_id"]))
echo "Welcome " . $_COOKIE["user_id"] . "!<br>";
else
echo "Welcome guest!<br>";
?>
<br>
<a href='next.php'>Next</a>
On the next page I have this php code:
<?php
header("Cache-Control: no-cache, must-revalidate, max-age=0"); // HTTP/1.1
header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date in the past
header('Pragma: no-cache');
setcookie("user_id", "", time()-(60*60*24), "/");
echo "<br /> Welcome " . $_COOKIE["user_id"] . "!<br>";
?>
How can I make sure the cookie is unset on the second page, or the page is fetched anew?
This depends on what you are trying to do. If you have a dependency on the cookie on the client, then you may want to unset it using the client (JavaScript). If the dependency is on the server, then it'd be tough to know what your problem is since you can just write the second part of the code to not depend on the cookie after you "unset" it.
I don't fully recommend this as it's an extra page load that's probably not necessary, but you could also force the sending of headers.
if (isset($_COOKIE['user_id'])) {
setcookie(/* your params */);
header('Refresh: ' . $_SERVER['REQUEST_URI']);
exit;
}
you can try using the following code in second page
setcookie("user_id", "");
I hope you can solve your problem.
How do I Limit some information displayed from the database and add a link eg "More" to enable read all information in a drop down using PHP. such as what is on facebook (Read more...). I am dealing with a lot of content and I dont want it all displayed at once.
Here is part of the code
echo "<p>".$row['Firstname']." ".$row['Lastname']."</p>";
echo "<p>".$row["Course"]." | ".$row["RegID"]."</p>";
echo "<p>".$row["Email"]."</p>";
echo "<p>"."Tel:".$row["Telephone"]."</p>";
echo "<p>".$row["info"]."</p>";
The code is running well only that I want to limit the information
echo "<p>".$row["info"]."</p>";
so that not all is displayed
Thanks
Use Jquery-ui click on "view source" and you'll see it's very simple really, just set the row that you want as the header (what's clicked to show the rest) and store the rest in a div below.
Split info into two strings, one intro, and the rest. Display only the intro to begin with. Insert a link that displays the rest when clicked.
$intro = substr($row['info'], 0, 200);
$rest = substr($row['info'], 200);
echo sprintf(
<<<HTML
<p>
<span class="intro">%s</span><span class="rest" class="display: none">%s</span>
Show more
</p>
HTML
, htmlentities($intro)
, htmlentities($rest)
);
displayRest is a Javascript-function that, given a link, finds the previous span with class rest, shows it and removes the link. I leave it as an exercise to implement this in a way that fits your project. You can go with native Javascript, or use a library such as jQuery, YUI, MooTools, Prototype etc.
if(isset($_POST['more']))
{
$query="select col1,col2,col3, ... ,colN from tableName ";
}
else
{
$query="select col1,col2,col3 from tableName ";
}
//HTML
<form method="post">
<input type="submit" name="more" value="More" />
</form>
//PHP
$records=mysql_query($query);
while($row=mysql_fetch_assoc($records))
{
//Display
}
The limit must be fixed on the SQL request.
// If you want to transmit limitation with a GET PARAMETER.
// You can also $_POST ur data.
$limitation = $_GET['limit'];
//..... And in your SQL REQUEST
$sql = "SELECT * FROM your_table LIMIT 0 , $limitation";
//And in the link....
echo 'Show only 10 Results'
?>
You can optimize that and add security precaution to prevent errors when $limitation receive empty or non numeric parameters.
<?php if(isset($_GET['limit']) && !empty($_GET['limit']) && !preg_match(EXPRESSION, $_GET['limit'])){
//YOU CAN DO THE LIMITATION WHITOUT SQL ERRORS
}
else{
//ERROR DIRECTIVE
}
?>