Checking if request is post back in PHP [duplicate] - php

This question already has answers here:
Detecting request type in PHP (GET, POST, PUT or DELETE)
(14 answers)
Closed 9 years ago.
How can I check if the request is a post back in PHP, is the below ok?
if (isset($_POST["submit"]))
where submit is the name of the <input type="submit" />

That will work if you know and expect such a submit button on the same page.
If you don't immediately know anything about the request variables, another way is to check the request method:
if (strtoupper($_SERVER['REQUEST_METHOD']) == 'POST')
As pointed out in the comments, to specifically check for a postback and not just any POST request, you need to ensure that the referrer is the same page as the processing page. Something like this:
if (basename($_SERVER['HTTP_REFERER']) == $_SERVER['SCRIPT_NAME'])

You want $_SERVER['REQUEST_METHOD'] == 'POST'.
Yours is a very similar although less general question than this one.
This is probably a better approach than actually checking a post variable. For one, you don't know whether that variable will be sent along. I have the hunch that some browsers just won't send the key at all if no value is specified. Also, I'd worry that some flavors of PHP might not define $_POST if there are no POSTed values.

If you want to have a generic routine without dependency "method" (post/get) and any other names of the forum elements, then I recommend this
<?php
$isPostBack = false;
$referer = "";
$thisPage = "http://".$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF'];
if (isset($_SERVER['HTTP_REFERER'])){
$referer = $_SERVER['HTTP_REFERER'];
}
if ($referer == $thisPage){
$isPostBack = true;
}
?>
now the if $isPostBack will be true if it is a postback, false if not.
I hope this helps

Yes, that should do it.
Careful when you're using image type submits, they won't send the name attribute in some browsers and you won't be able to detect the POST. Smashed my head against the desk a few times until I realized it myself.
The workaround for that is to add a hidden type input as well.

Yes. You could also use if(array_key_exists('submit', $_POST))

Related

Reason for checking if $_SERVER['REQUEST_METHOD'] == 'POST'?

I've searched about a dozen answers on here relating to:
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
}
Yet I still haven't found an answer to why.
Why is this done if we've already set the <form method="post">?
Doesn't that mean that it's the only form method here?
If the user comes from the previous form then the request method is POST indeed. But anyone can make a request to your server, for example via CURL or a custom program. There is no stopping people making random request to your pages.
Therefore you cannot be sure that the request method on the server is indeed POST, and all data is present.
In another context it can be used to check if the form has actually been submitted. For example:
<?php if($_SERVER['REQUEST_METHOD'] == 'POST') { ?> <!-- The server has recieved something via POST! -->
Thank you for submitting the form!
<?php } else { ?> <!-- No postdata, lets show the form! -->
<form method='POST'> <!-- By setting the method we ask that the client does a post request. -->
<input type='submit' />
</form>
<?php } ?>
There are two ways you can send forms from the client to the server: GET and POST. They are defined in RFC 2616 (HTTP), but the difference you can directly see is that GET gets displayed in the URL and POST doesn't.
Keep in mind that this is only for the browser on the client side to decide which way they send content to the server.
Regarding $_SERVER['REQUEST_METHOD']:
Which request method was used to access the page; i.e. 'GET', 'HEAD', 'POST', 'PUT'.
Note: PHP script is terminated after sending headers (it means after producing any output without output buffering) if the request method was HEAD.
One reason why you might want to use
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
}
might be to check if a form was submitted. But keep in mind: People can send POST requests without actually using your form! So you have to check the other data anyway.

Removing POST data so back button won't display Document Expired

When my page does a post, I store all the $_POST data in a separate $_SESSION var. I know that a back button to this same page is by design to show the Document Expired message. My hope is to fool the browser into thinking that there was really never any $_POST data and so not to display the Document Expired message when coming back to it. I am forcing a complete refresh of the page so I am not worried about receiving old data, since I have it stored in the session.
I have tried to unset($_POST) hoping this will stay with the page. but the $_POST data must be cached / stored and returns with a refresh or back button. Is what I am trying to do possible? Any ideas?
* UPDATE *
My solution / answer is posted below. It posts to a separate form, which redirects back to the original form for processing. Not sure why the down vote. It has been working great for months and I no longer receive Document Expired messages. It also prevents duplicate posting.
You can achieve this using the post - redirect - get design pattern.
http://en.wikipedia.org/wiki/Post/Redirect/Get
A more standard way to implement this pattern is to display, validate and save the form on one page.
The following solution has these advantages :
1. All form related code is in one place.
2. Server side validation is simple
I have two pages, form.php and after.php.
form.php :
if(isPosted()){
if(dataIsValid($postedData)){
// dataIsValid should set $message to show to the user
saveData($postedData);
redirect('after.php');
die();
}
} else {
$postedData = $defaultValues;
}
showForm($postedData, $message);
You can add the following to the beginning of your script to solve this issue.
header("Cache-Control: max-age=300, must-revalidate");
Simplest solution that comes to mind? Don't directly do the post, catch the event and submit the form through AJAX. Then on success, redirect.
An example using jQuery:
$('#some_form').submit(function() {
$.post($(this).attr('action'), $(this).serialize(), function() {
window.location = "/some/success/url.php";
});
return false; // Prevent the form submission & any other events triggered on submit
});
Because the POST never got added to the browser history, you won't have that issue.
However, note that the POST url is now different than the one you load; you can make it the same by checking whether a POST or a GET was done server-side, but either way, you have to do a bit of extra work to "remember" the results of the POST.
* UPDATE *
Here's my solution.
I am aware that with post-redirect-get the POST is usually back to the same page for processing before being redirected away from the form with a GET to another destination. However, I need to be able to return to the original page for re-editing (as in a document model where the user can SAVE work in progress). Therefore doing the POST to a second page and redirecting back to the original was my idea of getting rid of the "EXPIRED" message since the editing form would not have post data associated with it. I have extended this (not shown) to include $_FILE and other situations (e.g. using it with a href as well). Not sure why the downvote. This has been working great for months now and accomplishes the task. I no longer receive "Document Expired" messages. In addition, all $_POST processing is accomplished in the original file.
testform.php
<?php
session_start();
if (isset($_GET) && count($_GET)>0){
// process get
var_dump($_GET);
}
if (isset($_SESSION['post-copy'])){
// return post vars to $_POST variable so can process as normal
$_POST = $_SESSION['post-copy'];
// unset the session var - with refresh can't double process
unset($_SESSION['post-copy']);
// process post vars
var_dump($_POST);
}
?>
<form method='post' action='__b.php?redirect=<?php echo $_SERVER['PHP_SELF'] ?>&help=me' enctype='multipart/form-data'>
<textarea name='descr' id='descr'>ABCD</textarea>
<input type='submit' value='Go'>
</form>
redirect.php
<?php
if (!isset($_SESSION)){
session_start();
}
if (isset($_POST)){
$_SESSION['post-copy'] = $_POST;
}
// retrieve the url to return to
if (isset($_GET['redirect'])){
$url = $_GET['redirect'];
}
// if multiple query string parameters passed in get, isolate the redirect so can build querystring with the rest
if (isset($_GET) && count($_GET) > 1){
$get = $_GET;
foreach ($get as $key => $val){
if ($key == 'redirect'){
// remove from rest of passed get query string
unset($get[$key]);
}
}
if (count($get) > 0){
$url .= (strpos($url,"?")===false ? "?" : "&") . http_build_query($get);
}
}
if ($url!==""){
header("Location: " . $url);
}
?>

PHP initializing variables [duplicate]

This question already has answers here:
How to set PHP not to check undefind index for $_GET when E_NOTICE is on?
(3 answers)
Closed 9 years ago.
Im watching several php tutorials, and many of them start something like that:
<?php
if(!$_POST['username']){
..
..
};
?>
or
<?php
$username = $_POST['username'];
..
..
?>
but everytime I visit the page for the first time, it prints an error because $_POST['username'] was not initialize.
How can I I fix this?
thank u
There are four main HTTP methods you can use when making a request to a webserver: GET, POST, DELETE, and PUT. With each of these, you can pass variables with your request that PHP allows you to access. For GET and POST, you can access the variables with the corresponding arrays: $_GET & $_POST, respectively.
If you've never dealt with HTTP methods before, that's because you don't need to really think about it. This is because of the fact that when you type a URL into your browser and hit go, it uses the GET method by default.
So, in this case, what's probably going on is that you're just not making a POST request at all when you load your page. And even if you were, you'd need to have the proper POST variable defined to access it, which in this example would be username.
Since one of the above isn't true, the value of the variable is null. And when you try to access a null value in PHP, the script throws an error (as you've seen). You can change this, but I wouldn't recommend it. I like to know that I'm properly handling my null variables when I write code. But maybe that's just me.
The solution that I recommend, and that others have suggested, is to use the isset() function to see if the variable is defined. This will prevent your code from breaking. Check out the isset documentation for more.
<?php
if(isset($_POST['username'])){
..
..
}
?>
You can set error_reporting to E_ALL ~E_NOTICE
See the documentation on this: http://php.net/manual/en/function.error-reporting.php
or disable it globally in the php.ini file.
use isset($_POST['username'])
if(isset($_POST['username']))
{
.
.
.
}
$_POST['username'] is trying to get the 'username' variable which included the the POST http request to your page (think submitting a form). Normal browsing to a page is an http GET request.
Try using this to avoid issues:
<?php
if(isset($_POST['username'])) {
... if POST and includes a username value, do this ...
} else {
... otherwise do this stuff ...
}
Read me for more info on types HTTP requests: http://techforum4u.com/content.php/229-HTTP-Request-GET-HEAD-POST-PUT-DELETE-OPTION-TRACE
That's because you didn't recieve a value via POST (like from a form post). Add an isset() validation as others are suggesting. Take a look at http://php.net/manual/es/function.isset.php

Prevent direct access to action form [duplicate]

This question already has answers here:
CSRF (Cross-site request forgery) attack example and prevention in PHP
(4 answers)
Closed 9 years ago.
I have a form.php wich action call sql.php file like:
SQL.PHP
if ($_REQUEST['action'] == "add") {
}
if ($_REQUEST['action'] == "edit") {
}
I'm like to prevent direct access, because user can call from browser url: http://sql.php?action=add
One way is check if a submit. Seem work well.
if( isset($_POST['Submit']) && ($_POST['Submit'] == "Submit") )
{
echo "direct access not allowed";
}
There is better alternatives?
Use the $_SERVER['HTTP_REFERER'] array to detect if someone is accessing your page directly by typing in it into the browser, or comming from another one of your pages, by a use of links from a page.
So, basically.
if($_SERVER['HTTP_REFERER'] == 'about.php'){
//let user do something
}
So, the $_SERVER['HTTP_REFERER'] global stores information of the pages you visit, and if you place echo that code, in your page, it will tell you from which page your are comming from. meaning, that if you only typed the page and access it, it will give 0/false value.
So, you can use it to detect if someone is directly typing the page or comming from one of your pages.
As others have indicated already, using tokens, and sessions would be a better idea since this method can be manipulated. So, I recommend you google them out
It should be if(!isset($_POST['Submit']) . Also if you use method="POST", it does not throw your parameters like ?action=add at the browser. method="GET" does it.

Optional Form - How do I remove the "this page has used data..." message? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
I am confused about PHP Post/Redirect/Get
I have a form on a page, so I get the "this page has used data, are you sure you want to refresh" message when I reload the page.
I looked into the HTTP-303 response code, which gets rid of the message (I'm on Chrome btw) until I submit the form once, and then it starts bugging me again.
Basically, I have an optional "contact me" form, that shouldn't throw a prompt if the page is refreshed. I don't think/see why I should need a separate page for submission for a short form like this. Can anyone help me out?
Your best option is to use Ajax. That way you don't need to reload.
I usually use it with JQuery.
So you end up with something like:
function send_message(vMessage,vWho) {
$.ajax({
url:"messageSender.php",
data:{message:vMessage,from:vWho},
type:"POST",
success:function(result) {
// DO SOMETHING HERE, LIKE AN ALERT
}
});
}
Final Solution:
How to prevent form resubmission, on the same page
You should have the action="something" tag. Required in HTML5
Check if a form was submitted. If you don't, and have a header('Location: ...') it will be like an infinite loop (crap out). So something like if (isset($_POST['some_submit_btn'])) {
Do you processing logic
Do header('Location: same_page') (eg: header('Location: ' . $_SERVER['PHP_SELF'])) and exit
Your page can now refresh regularly, even after submitting a form. The redirect clears the POST request or whatever.
Others have pointed out Ajax is a simpler solution. I've accepted it as an answer, but in case anyone wants to do it this way I put this for reference.
Note: If you want to pass data between the two pages/refreshes, you have to pass it through sessions or cookies (I prefer sessions). I don't think there's a "clean" workaround
You need to redirect after you saved the form data. It can be done on the same page, it's not a problem, you just need to issue a GET request instead of a POST.

Categories