run update query only once in php - php

is it possible to run update query only once, here i have a link or button where if he clicked his profile will be changed(updated) automatic and brought him at myaccount.php page .
All thing going fine and working properly but the main problem occuring when reloading the same page(myaccount.php) and his profile updating with every time. But i want his profile should only change when he clicked the link or that button only once...i set link as
<a href='myaccount.php.php?age =$age && status= $status' target='_blank' style='color:#E07707;font-weight:bold;'>Update Profile</a></div></div><br>
and I set update query on myaccount.php as:
if(($age== '') || ($location= '') || ($status= ''))
{
$newquery1 = "update $tabl_u something...................... where id='$id'";
}
there is no submit button no other events for update data, but only clicked by url or link where i passed some id for update data, i hope my question is done by my side and hope you will understand if something i missed or missing please let me know ...feel free to ask anything regarding my question..plz help i realy need help....thanks in advance !

You should never do any data change in a GET request.
As said in the HTML 4 and HTTP specifications
If the processing of a form is idempotent (i.e. it has no lasting observable effect on the state of the world), then the form method should be GET. Many database searches have no visible side-effects and make ideal applications of query forms.
If the service associated with the processing of a form has side effects (for example, modification of a database or subscription to a service), the method should be POST.
For example, what happens if the user has a "web accelerator" that pre loads all the urls on the page ?
You should also check that the request indeed come from the user on your website, or you open the door to a very easy CSRF vulnerability.
With that said, the usual method to fix what you want is that, after updating the user status in your database, you should issue a redirect to the non-modifying page.
base page -> click on change link -> change the status in database and redirect to base page again
<?php
if(($age== '') || ($location= '') || ($status= '')) {
mysqli_query(/* update whatever */);
header('Location: myaccount.php');
exit;
}
If he refresh the page, he is on base page so it won't change anything.
If he press "back" in his browser, he goes back to the page base too (pages that issues a redirect aren't saved in the browser history).

After you do the update, don't output anything. Instead, send the user somewhere else, for example:
header("Location: myaccount.php");
exit(0);
That way, the GET data is lost from the link and reloads won't repeat the update, while clicking the "Back" button would take the user to the page (probably the form) before the update, so - again - the update will not be repeated.

session_start();
if(isset($_GET)) {
if(empty($_SESSION['update'])) {
//update data
$_SESSION['update'] = 'Finished';
echo 'updating is finished';
}else{
echo 'Your details have beed updated already';
}
}

Related

Return to the called page in CakePHP 3

I have an action, /controller/edit, which can be clicked to from multiple locations (e.g. /controller/index and /controller/view).
Once the user has finished editing the record and clicks save, I want them to return to wherever they came from (/controller/index or /controller/view respectively).
At first I tried storing each page the user visits in their session (e.g. home > index > edit), and then redirecting to the second-to-last entry in that list - and that works fine right up until they open another tab. If, while they're editing the record they open another tab and go off somewhere else, their session variable keeps being built on (home > index > edit > help > help page), and when the time comes to redirect the second-to-last entry no longer contains the correct action.
How can my edit action /controller/edit, on save, redirect the user back to the referring page they came from to get there, independent of whatever the user has done in other tabs?
Edit: I can't use referrer after save because the process is this:
User is on either /controller/index or /controller/view
User clicks into /controller/edit (referrer is /controller/index or /controller/view)
User makes changes to record and clicks save, which form submits to /controller/edit (referrer is /controller/edit)
I now want to redirect them to either /controller/index or /controller/view, but that is no longer in the referrer
Use to return to wherever you came from
return $this->redirect($this->referer());
I had to deal with the same problem and I did this:
1) In my controller, in the GET section, set the referer to a view variable like this:
$this->set('redirect', $this->referer());
2) In the form, set a hidden control named "redirect":
echo $this->Form->hidden('redirect', ['value' => $redirect]);
3) In the controller, after processing the POST request, redirect to the value of the hidden input:
if (isset($this->request->data['redirect'])) {
$this->redirect($this->request->data['redirect']);
}
Of couse, this could be abstracted into a component and maybe use session, but this approach worked for me.
You can redirect to the referring page, using return $this->redirect($this->referer());
As per the Documentation it will redirect you to the referring page.
This is extension to #DanielCoturel answer. Step 1. in his answer is redundant (see my comment). I did it more globally by overwriting redirect() function in AppController.php (still have to add 'redirect' input to all forms):
public function redirect($url, $status = 302)
{
if ($this->request->getData('redirect', '')) {
return parent::redirect($this->request->getData('redirect'), $status);
}
return parent::redirect($url, $status);
}

Redirect website from within frame PHP

I have a web page, let's call it main.php which displays an image of football field and some players distributed on the field. However, that page uses list.php as a right side frame that loads a list of players.
What happens is, when the user clicks on a player on the field (main.php), let's say on the image of the Goal Keeper (GK), a list of GKs from world wide teams will load in right list fram (list.php). This is by using ajax.
So far we are good.
The current situation is, when session times out and the user clicks on a player from the field, the list on the right does not load, instead, list of players disappears from the list and a message says "Please login" is displayed on the right side frame (list.php)
The objective is, when session times out I want the whole website to redirect to the main page index.php
The problem is, I already put the redirecting code just before the code that is responsible of displaying the message "Please login". But what happened is, the redirection happens from within the frame, so i ended up having main.php displaying the field, and list.php displaying the main page!
Here's the code I added.
$user_id = NSession::get('user_id');
if (!isset($user_id))
{
NSession::removeall();
General::Redirect('index.php');
}
They are using Smarty. and btw, I added the same code to top of main.php, and now if user tries to access main.php without logging in, it will redirect him to the main page, so the code works!
n.b. The project is not mine, it belongs to the company I work in.
And I don't know which code is checking the session, all what I know is, if the user click on a player from the field after the session timeout, the "Please Login" message will be shown in the frame.
I'm guessing the redirect is essentially the same as using a header() function. It isn't possible to specify a target using a php redirect as it is server-side - specifying the target is client-side.
You would need to print something like this to the screen:
<script type="text/javascript">window.open('index.php','_parent');</script>
And that will redirect the user to the index.
Using frames for such purpose is... well... so 80ish...
Anyway, the frames are probably named in such a scenario. This means you can address them, but also that you have to address them. Just loading an url inside the "current" frame does exactly that, which is why your approach won't work.
If you really have to go with that frame based approach, then you will have to use javascript to address all known frames and redirect them.
Maybe you can use some javascript inside of your frame like so :
<script type="text/javascript">
window.top.location = 'YourPage.html';
</script>
Hope this helps
The issue was that the session expires while I'm on main.php. Therefore, any subsequent Ajax requested will fail since all requests requires session to be active.
the problem was that the Ajax request being sent from the IFrame (the IFrame is inside main.php and points to list.php thru Ajax calls) is failing due to session expiry.
So I've fixed this issue by adding another two session checks, one on main.php, list.php using PHP (check for session, if it's there, redirect). And in the main container, main.php, I check for the session via JS, interval Ajax requests to check the session, if session has ended, then use redirect using JS.
PHP:
$user_id = NSession::get('user_id');
if (isset($_POST["checklogin"]))//check loging
{
die(isset($user_id) ? "true" : "false");
}
if (!isset($user_id) || $user_id == "")
{
NSession::removeall();
General::Redirect('login.php');
}
JavaScript:
jQuery(document).ready(function($) {
$(window).focus(function() {
checkSession();
});
});
function checkSession()
{
$.ajax({
type: "POST",
data: {"checklogin": "cl"},
url: "list_players.php",
success: function(result) {
if (result === "false")
{
if (FIELD.showMessage === false)
{
FIELD.showMessage = true;
alert("Your session has been closed\nYou will be redirected to login page now. ");
window.location.href = ("login.php");//incase user clicks OK
}
}
}
});
}

How to prevent the "Confirm Form Resubmission" dialog?

How do I clean information in a form after submit so that it does not show this error after a page refresh?
See image (from chrome):
The dialog has the text:
The page that you're looking for used
information that you entered. Returning to that
page might cause any action you took to be
repeated. Do you want to continue?
I want this dialog not to appear.
This method works for me well and I think the simplest way to do this is to use this javascript code inside the reloaded page's HTML.
if ( window.history.replaceState ) {
window.history.replaceState( null, null, window.location.href );
}
Edit: It's been a few years since I originally posted this answer, and even though I got a few upvotes, I'm not really happy with my previous answer, so I have redone it completely. I hope this helps.
When to use GET and POST:
One way to get rid of this error message is to make your form use GET instead of POST. Just keep in mind that this is not always an appropriate solution (read below).
Always use POST if you are performing an action that you don't want to be repeated, if sensitive information is being transferred or if your form contains either a file upload or the length of all data sent is longer than ~2000 characters.
Examples of when to use POST would include:
A login form
A contact form
A submit payment form
Something that adds, edits or deletes entries from a database
An image uploader (note, if using GET with an <input type="file"> field, only the filename will be sent to the server, which 99.73% of the time is not what you want.)
A form with many fields (which would create a long URL if using GET)
In any of these cases, you don't want people refreshing the page and re-sending the data. If you are sending sensitive information, using GET would not only be inappropriate, it would be a security issue (even if the form is sent by AJAX) since the sensitive item (e.g. user's password) is sent in the URL and will therefore show up in server access logs.
Use GET for basically anything else. This means, when you don't mind if it is repeated, for anything that you could provide a direct link to, when no sensitive information is being transferred, when you are pretty sure your URL lengths are not going to get out of control and when your forms don't have any file uploads.
Examples would include:
Performing a search in a search engine
A navigation form for navigating around the website
Performing one-time actions using a nonce or single use password (such as an "unsubscribe" link in an email).
In these cases POST would be completely inappropriate. Imagine if search engines used POST for their searches. You would receive this message every time you refreshed the page and you wouldn't be able to just copy and paste the results URL to people, they would have to manually fill out the form themselves.
If you use POST:
To me, in most cases even having the "Confirm form resubmission" dialog pop up shows that there is a design flaw. By the very nature of POST being used to perform destructive actions, web designers should prevent users from ever performing them more than once by accidentally (or intentionally) refreshing the page. Many users do not even know what this dialog means and will therefore just click on "Continue". What if that was after a "submit payment" request? Does the payment get sent again?
So what do you do? Fortunately we have the Post/Redirect/Get design pattern. The user submits a POST request to the server, the server redirects the user's browser to another page and that page is then retrieved using GET.
Here is a simple example using PHP:
if(!empty($_POST['username'] && !empty($_POST['password'])) {
$user = new User;
$user->login($_POST['username'], $_POST['password']);
if ($user->isLoggedIn()) {
header("Location: /admin/welcome.php");
exit;
}
else {
header("Location: /login.php?invalid_login");
}
}
Notice how in this example even when the password is incorrect, I am still redirecting back to the login form. To display an invalid login message to the user, just do something like:
if (isset($_GET['invalid_login'])) {
echo "Your username and password combination is invalid";
}
It has nothing to do with your form or the values in it. It gets fired by the browser to prevent the user from repeating the same request with the cached data. If you really need to enable the refreshing of the result page, you should redirect the user, either via PHP (header('Location:result.php');) or other server-side language you're using. Meta tag solution should work also to disable the resending on refresh.
After processing the POST page, redirect the user to the same page.
On
http://test.com/test.php
header('Location: http://test.com/test.php');
This will get rid of the box, as refreshing the page will not resubmit the data.
It seems you are looking for the Post/Redirect/Get pattern.
As another solution you may stop to use redirecting at all.
You may process and render the processing result at once with no POST confirmation alert. You should just manipulate the browser history object:
history.replaceState("", "", "/the/result/page")
See full or short answers
You could try using AJAX calls with jQuery. Like how youtube adds your comment without refreshing. This would remove the problem with refreshing overal.
You'd need to send the info necessary trough the ajax call.
I'll use the youtube comment as example.
$.ajax({
type: 'POST',
url: 'ajax/comment-on-video.php',
data: {
comment: $('#idOfInputField').val();
},
success: function(obj) {
if(obj === 'true') {
//Some code that recreates the inserted comment on the page.
}
}
});
You can now create the file comment-on-video.php and create something like this:
<?php
session_start();
if(isset($_POST['comment'])) {
$comment = mysqli_real_escape_string($db, $_POST['comment']);
//Given you are logged in and store the user id in the session.
$user = $_SESSION['user_id'];
$query = "INSERT INTO `comments` (`comment_text`, `user_id`) VALUES ($comment, $user);";
$result = mysqli_query($db, $query);
if($result) {
echo true;
exit();
}
}
echo false;
exit();
?>
I had a situation where I could not use any of the above answers. My case involved working with search page where users would get "confirm form resubmission" if the clicked back after navigating to any of the search results. I wrote the following javascript which worked around the issue. It isn't a great fix as it is a bit blinky, and it doesn't work on IE8 or earlier. Still, though this might be useful or interesting for someone dealing with this issue.
jQuery(document).ready(function () {
//feature test
if (!history)
return;
var searchBox = jQuery("#searchfield");
//This occurs when the user get here using the back button
if (history.state && history.state.searchTerm != null && history.state.searchTerm != "" && history.state.loaded != null && history.state.loaded == 0) {
searchBox.val(history.state.searchTerm);
//don't chain reloads
history.replaceState({ searchTerm: history.state.searchTerm, page: history.state.page, loaded: 1 }, "", document.URL);
//perform POST
document.getElementById("myForm").submit();
return;
}
//This occurs the first time the user hits this page.
history.replaceState({ searchTerm: searchBox.val(), page: pageNumber, loaded: 0 }, "", document.URL);
});
I found an unorthodox way to accomplish this.
Just put the script page in an iframe. Doing so allows the page to be refreshed, seemingly even on older browsers without the "confirm form resubmission" message ever appearing.
Quick Answer
Use different methods to load the form and save/process form.
Example.
Login.php
Load login form at Login/index
Validate login at Login/validate
On Success
Redirect the user to User/dashboard
On failure
Redirect the user to login/index

How to hide php actions from history?

Is it possible to tell the browser that he should not remember the action scripts page?
So when you delete a headline for example. The get action will be ?d=ID where ID is the id of the headline. After removing the headline go to the page without the get variable in the url (the header part).
<?php
if(isset($_GET['d']) && preg_match('{^[0-9]{1,3}$}',$_GET['d'])){
$hid = $_GET['d'];
$deletesql = "DELETE FROM headlines WHERE hid = $hid";
mysql_query($deletesql);
header('Location: panel.php');} ?>
But now you browser history shows the link panel.php?d=23
Can prevent the browser from remembering the page? Maybe a 303 header?
You should use POST instead of GET for this. That way the browser will prompt the user if he wants to send the information again. (typically the id argument)
Make the ID hidden in the form and then get it in the form action part using $_POST and then do the delete action and redirect once delete is successful to avoid user from re posting the form.

Prevent form resubmit in Zend framework?

An action within a controller generates the next id from the database and displays it on screen as reference. How can I prevent the action being called again if the user clicks refresh.
The post-redirect-get pattern with Zend Framework would generally involve leaving the action of the form empty (so it posts to itself) and then redirecting when you don't want to display the form again (so upon success).
public function newAction() {
$form = new Form_Foo();
if($this->_request->isPost()) {
if($form->isValid($this->_request->getPost()) {
//save or whatever
return $this->_redirect('path/to/success');
}
// else fall through
}
$this->view->form = $form;
}
if ($this->isPost()) {
// Check validation
if ($error) {
$dataToMove = array();
// $dataToMove is array that you want to pass with redirect
// It can be an array of errors or form data that user has entered
// Use FlashMessenger helper to pass data to redirection via Zend_Session
$this->_helper->getHelper('FlashMessenger')->addMessage($dataToMove);
// And redirect page to form url
$this->_helper->getHelper('Redirector')->goToUrl('/form/url/');
}
// If not posted, get data from FlashMessenger
$data = $this->_helper->getHelper('FlashMessenger')->getMessages();
// And assign to view or make that you want
$this->view->formData = $data;
Although this is older post people still come here for answers, so let me help a bit more.
Redirecting form is great and useful but we are still not preventing peple from clicking back button and resubmitting that way.
The solution is to either show the form as popup and make it disapear when done (easily done with jquery) or generate unique id for each transaction and checking if id was previously used.
See article: http://www.boutell.com/newfaq/creating/stoprefresh.html
Hope it helps.
You can do this by implementing a 302 redirect
header('HTTP/1.1 302 Found');
header('Location: displayId.php?id=5');
die();
Assuming you have these pages
form.php
processForm.php
displayId.php
Form.php only displays form and sends data via POST to processForm.php.
Within processForm.php you can parse data and issue the redirect to displayId.php with id you want to display in GET parameter.
This way when user refreshes the page (displayId.php) the form data is not processed again.
I know you're trying to do this in Zend Framework but I'm just saying I'm after the same functionality. Just moved everything to ZF and I'm quite disappointed to see that this functionality isn't built in.
I used to have every form submit to process.php which processed all GET, POST requests and then saved the results (like error and success messages) and redirected you to the new place.
If $_SESSION['post_data'] was set, I would $_POST = $_SESSION['post_data']; and then remove it from the session.
This worked great but now I'm gonna need the same in ZF :D As I say... a little disappointed as I don't believe ANYONE wants a dialog to appear asking about resubmitting data.. what the hell does that mean to your enduser? nothing!

Categories