Jump to content

Empty $_POST on form submission?


moobs

Recommended Posts

I created a simple birthday calculator that allows a user to submit their birthday, and then a bunch of facts relative to that date gets spit out. Everything works as intended in chrome, but not in firefox or safari. I'm not receiving any errors. The page gets redirected as it should when the form is submitted, but the form data is be placed into the $_POST array and then set to a session variable as it should. I have other forms on my site that work with all browsers, so I'm not sure where I've gone wrong.

 

This is how I'm passing the $_POST data to $_SESSION:

 

session_start();
error_reporting(E_ALL); ini_set('display_errors',1);


if(count($_POST) > 0) {
        $_SESSION['dob-month'] = $_POST['dob-month'];
$_SESSION['dob-day'] = $_POST['dob-day'];
$_SESSION['dob-year'] = $_POST['dob-year'];


if(isset($_POST['submit'])){
$_SESSION['submit'] = 1;}


header("HTTP/1.1 303 See Other");
header("Location: https://$_SERVER[HTTP_HOST]/poop-calculator/");
        die();
    }
elseif (isset($_SESSION['dob-month'])||isset($_SESSION['dob-day'])||isset($_SESSION['dob-year'])){
        $month = $_SESSION['dob-month'];
$day = ltrim(sanitizeNumInput($_SESSION['dob-day']),'0');


$year = sanitizeNumInput($_SESSION['dob-year']);
$submit = $_SESSION['submit'];


        /*
            Put database-affecting code here.
        */




        session_unset();
        session_destroy();
    }else{
$month = null;
$day = null;
$year = null; 

} 

Here's how I'm creating the form:

 

echo '
<div class="calc-holder">
<form method="post" action="/calculator/"> 


<div class="dobRow">
<div class="dobMonth">
<select name="dob-month">
'.$monthOptions;


while($i <= 12){
foreach($monthList as $key => $val){
if($i != $month){
echo '<option value="'.$key.'">'.$val.'</option>';}
$i++;
}
}


echo '


</select>
</div><!--end dobMonth-->
<div class="dobDay"><input type="text" name="dob-day" maxlength="2" '.$dayHolder.'/></div><!--end dobDay-->
<div class="dobYear"><input type="text" maxlength="4" max="'.date('Y').'" name="dob-year" '.$yearHolder.'/></div><!--end dobYear--> 
<div class="dobSubmit"><input type="submit" name="submit" value="Calculate"/></div><!--end dobSubmit-->
</div><!--end dobRow-->




</form>
</div><!--end calc-holder-->';

I've been struggling with this all day, any help would be greatly appreciated.

Link to comment
Share on other sites

So the problem is that when you submit the form in Firefox or Safari the $_POST is empty?

 

Also... poop calculator? WTF? :/

I've narrowed the problem down to my post redirect get method. I reproduced the problem I'm having with a much smaller function that should make it easier to figure out where I'm going wrong.

 

function testForm(){


session_start();
error_reporting(E_ALL); ini_set('display_errors',1);


if(count($_POST) > 0) {
        $_SESSION['testFormText'] = $_POST['testFormText'];


if(isset($_POST['testSubmit'])){
$_SESSION['testSubmit'] = 1;}


header("HTTP/1.1 303 See Other");
header("Location: https://$_SERVER[HTTP_HOST]/poop-facts/");
        die();
    }
elseif (isset($_SESSION['testFormText'])){
        $text = $_SESSION['testFormText'];


$submit = $_SESSION['testSubmit'];


        /*
            Put database-affecting code here.
        */




        session_unset();
        session_destroy();
    }else{
$text = null; 


}




echo '<div class="testForm">
<form method="post" action="">
<input type="text" name="testFormText"/>
<input type="submit" name="testSubmit" value="submit">
</form>
</div>
'; 




echo $text;
}

The function works correctly in chrome. Enter something into the input and submit the form. The data is sent to $_POST then set as a session variable. If the session is set, it is then echoed as the variable $text after the page is redirected back to itself from submitting the form. This however does not work with firefox and safari.

Link to comment
Share on other sites

nope.  not without more data regarding the actual point of failure.  start putting in debugging outputs at key points along the process using var_dump() and see exactly when things stop working in each browser.

Thanks for the suggestion. Upon adding in dumps at different stages I found that the cause is:

 

        header("HTTP/1.1 303 See Other");
        header("Location: https://$_SERVER[HTTP_HOST]/poop-facts/");
        die();

I would like to have a 303 redirect to avoid creating duplicate submissions. From what I read online this is the way to do that, but I don't understand why chrome handles the request correctly and other browsers don't. Do you see anything wrong with this block, or can you reccomend an alternative method for post, redirect, get?

Link to comment
Share on other sites

I managed to get the form to process correctly by making a few changes and removing the header 303 redirect altogether. The problem I face now is duplicate form request when the page is refreshed because I need to have the output on the same page. Any suggestions?

Link to comment
Share on other sites

I managed to get the form to process correctly by making a few changes and removing the header 303 redirect altogether. The problem I face now is duplicate form request when the page is refreshed because I need to have the output on the same page. Any suggestions?

 

Typically the way this is done is to do the redirect after the form is processed. Where you're putting the $_POST variables into $_SESSION, redirecting, then processing from $_SESSION, you'll usually do it the other way around. Check to see if $_POST is set, process the data if it is. If the processing is successful, redirect the browser back to the current page. That way $_POST is clear, the form has been processed, and you don't need to muck about with stuffing things into $_SESSION when they're not entirely necessary. I can't remember the term/abbreviation for this method of handling data processing off the top of my head, sorry...

Link to comment
Share on other sites

Typically the way this is done is to do the redirect after the form is processed. Where you're putting the $_POST variables into $_SESSION, redirecting, then processing from $_SESSION, you'll usually do it the other way around. Check to see if $_POST is set, process the data if it is. If the processing is successful, redirect the browser back to the current page. That way $_POST is clear, the form has been processed, and you don't need to muck about with stuffing things into $_SESSION when they're not entirely necessary. I can't remember the term/abbreviation for this method of handling data processing off the top of my head, sorry...

Yeah that just sounds like the standard post redirect get pattern I've been trying to get working. Error checking in that order does make more sense, but I'm not sure if it will make a difference if it's checking the sessions vs $_post. I'll definitely give it a shot though and move my error checking validate $_POST first. 

 

I'll let you know how it turns out.

Edited by moobs
Link to comment
Share on other sites

Typically the way this is done is to do the redirect after the form is processed. Where you're putting the $_POST variables into $_SESSION, redirecting, then processing from $_SESSION, you'll usually do it the other way around. Check to see if $_POST is set, process the data if it is. If the processing is successful, redirect the browser back to the current page. That way $_POST is clear, the form has been processed, and you don't need to muck about with stuffing things into $_SESSION when they're not entirely necessary. I can't remember the term/abbreviation for this method of handling data processing off the top of my head, sorry...

 

I've gone through and and made all the changes to check the post array for errors. If no errors are found the variables are set to sessions and the page is redirected to itself to clear the post array. Once the page is reloaded from the redirect the sessions are set to standard variables and the sessions are unset and destroyed. 

 

Unfortunately I'm back where I started. Everything works great in chrome, but browsers like firefox and safari are not storing the sessions. Once redirected the page in those browsers does not output any results from the form submission and has an empty form.

 

So just to be clear some browsers are having trouble handling the header redirect and storing the session data, but I do not understand why.

header("Location: /poop-calculator/",TRUE,303);

Here's what I'm currently working with:

session_start();error_reporting(E_ALL); ini_set('display_errors',1);


if(count($_POST) > 0) {


//Error Checking


$EC = 0;


if (isset($_POST['submit'])&&empty($_POST['dob-month'])){
$EC++;
$errors[$EC] = "Select a month"; 
}
if (isset($_POST['submit'])&&empty($_POST['dob-day'])|| $_POST['dob-day'] < 1 || $_POST['dob-day'] > 31){
$EC++;
$errors[$EC] = "Enter a day between 1 and 31";
}
if (isset($_POST['submit'])&&empty($_POST['dob-year'])|| $_POST['dob-year'] < 1900 || $_POST['dob-year'] > date('Y')){
$EC++;
$errors[$EC] = "Enter a year between 1900 and ".date('Y');
}


if(!empty($errors)){
echo '<div class="woocommerce-error">
<div class="errorSpacer"></div>';


foreach($errors as $error){
echo '<div class="error-wrapper">
         <div class="erroWrapperLeft">
         <p class="errorIcon"></p>
            </div>
            <div class="erroWrapperRight">
             <p class="errorText">'.$error.'</p>
            </div>
       </div>';
  }
echo "</div>";
} 


//set sessions


if(empty($errors)&& isset($_POST['submit'])){
(isset($_POST['dob-month'])? $_SESSION['dob-month'] = $_POST['dob-month']:$_SESSION['dob-month'] = null);
(isset($_POST['dob-day'])? $_SESSION['dob-day'] = ltrim(sanitizeNumInput($_POST['dob-day']),'0'):$_SESSION['dob-day'] =  null);
(isset($_POST['dob-year'])?$_SESSION['dob-year'] = sanitizeNumInput($_POST['dob-year']):$_SESSION['dob-year'] =null);
(isset($_POST['submit'])?$_SESSION['submit'] = 1:$_SESSION['submit'] = null);


header("Location: /calculator/",TRUE,303);
}


//set variables and clear sessions


    }
if (isset($_SESSION['dob-month'])||isset($_SESSION['dob-day'])||isset($_SESSION['dob-year'])||isset($_SESSION['submit'])){
        (isset($_SESSION['dob-month'])? $month = $_SESSION['dob-month']:$month = null);
(isset($_SESSION['dob-day'])? $day = ltrim(sanitizeNumInput($_SESSION['dob-day']),'0'): $day = null);
(isset($_SESSION['dob-year'])?$year = sanitizeNumInput($_SESSION['dob-year']):$year=null);
(isset($_SESSION['submit'])?$submit = $_SESSION['submit']: $submit = null );




        session_unset();
        session_destroy();


    }
Edited by moobs
Link to comment
Share on other sites

Try replacing the end of your code with this and let us know what prints:

//set sessions
	if(empty($errors) && isset($_POST['submit'])){
		$_SESSION['dob-month'] = isset($_POST['dob-month']) ? $_POST['dob-month'] : null;
		$_SESSION['dob-day'] = isset($_POST['dob-day']) ? $_POST['dob-day'] : null;
		$_SESSION['dob-year'] = isset($_POST['dob-year']) ? $_POST['dob-year'] : null;
		
		print("<p>\$errors is empty and \$_POST['submit'] is set</p><p>Session is: </p><pre>".print_r($_SESSION,true)."</pre><p>\$_POST is: </p><pre>".print_r($_POST,true)."</pre>");
		die();
		
//		header("Location: /calculator/",TRUE,303);
	}
//set variables and clear sessions

print("<p>Outside conditionals: \$_SESSION is: </p><pre>".print_r($_SESSION,true)."</pre>");

}
if (isset($_SESSION['dob-month'])||isset($_SESSION['dob-day'])||isset($_SESSION['dob-year'])||isset($_SESSION['submit'])){
	$month = isset($_SESSION['dob-month']) ? $_SESSION['dob-month'] : null;
	$day = isset($_SESSION['dob-day']) ? $_SESSION['dob-day'] : null;
	$year = isset($_SESSION['dob-year']) ? $_SESSION['dob-year'] : null;
	
	print("<p>This is the other conditional branch. The date is {$month}-{$day}-{$year}</p>");
	die();
	
    session_unset();
    session_destroy();
}

Note that your ternaries were malformed, so I updated that. I don't know if that would cause the problem you were having, but it's worth a shot.

 

Actually, now that I think about it, are you sure this isn't an HTML issue? The php is handled on the server, so if it works on Chrome, it should work on Firefox, IE, Opera, what have you.

Edited by maxxd
Link to comment
Share on other sites

Try replacing the end of your code with this and let us know what prints:

 

Note that your ternaries were malformed, so I updated that. I don't know if that would cause the problem you were having, but it's worth a shot.

 

Actually, now that I think about it, are you sure this isn't an HTML issue? The php is handled on the server, so if it works on Chrome, it should work on Firefox, IE, Opera, what have you.

Thanks for the help. Changing that actually broke my page, but here's the output.

$errors is empty and $_POST['submit'] is set

Session is:

Array
(
    [dob-month] => 3
    [dob-day] => 13
    [dob-year] => 1989
)

$_POST is:

Array
(
    [dob-month] => 3
    [dob-day] => 13
    [dob-year] => 1989
    [submit] => Calculate
)

Link to comment
Share on other sites

Broke your page how? The die() statements are there to stop execution of the script at that specific point so you can see what's happening. So, in this case, your $_POST and your $_SESSION variables are both set. Is that supposed to happen with this set up? If not, take a step back and rethink the logical flow. If so, then comment out the die() statement, fill out the form again, submit, and keep stepping forward until you find the point where the $_SESSION variables are set in Chrome but not in FireFox.

Link to comment
Share on other sites

Broke your page how? The die() statements are there to stop execution of the script at that specific point so you can see what's happening. So, in this case, your $_POST and your $_SESSION variables are both set. Is that supposed to happen with this set up? If not, take a step back and rethink the logical flow. If so, then comment out the die() statement, fill out the form again, submit, and keep stepping forward until you find the point where the $_SESSION variables are set in Chrome but not in FireFox.

Okay so everything was passed through as expected section by section of your testing all the way to the final date. I decided to remove the comment from the redirect, and leave all the testing lines in to see what the output was.

 

Chrome works as expected only producing your final testing line, the date, as it should since the sessions have been unset.

 

Firefox however just reloads to an empty field with no output. The error checking does work in firefox, but if the form is filled out correctly the page reloads to a blank form as if it has been refreshed.

 

If you'd like I can make the page public and PM you the URL?

Edited by moobs
Link to comment
Share on other sites

Just an update, I've moved the error handling, setting sessions, and redirect to take place before the page loads. The sessions are assigned to variables, unset, and destroyed in a function within the body of the page. Since doing this the sessions are no longer set in chrome using a redirect. I believe this is actually progress because once I figure out why it should work in all browsers. Here's my updated code.

 

Pre-page processing: 

error_reporting(E_ALL); ini_set('display_errors', 1);//set sessions
session_start();
//Error Checking


$EC = 0;
$errors = array();


$_POST['dob-month'] = isset($_POST['dob-month'])?$_POST['dob-month']:null;
$_POST['dob-day'] = isset($_POST['dob-day'])?$_POST['dob-day']:null;
$_POST['dob-year'] = isset($_POST['dob-year'])?$_POST['dob-year']:null;




if (isset($_POST['submit'])&&empty($_POST['dob-month'])){
$EC++;
$errors[$EC] = "Select a month"; 
}
if (isset($_POST['submit'])&&empty($_POST['dob-day'])|| $_POST['dob-day'] < 1 || $_POST['dob-day'] > 31){
$EC++;
$errors[$EC] = "Enter a day between 1 and 31";
}
if (isset($_POST['submit'])&&empty($_POST['dob-year'])|| $_POST['dob-year'] < 1900 || $_POST['dob-year'] > date('Y')){
$EC++;
$errors[$EC] = "Enter a year between 1900 and ".date('Y');
}


if(isset($_POST['submit'])){
if(empty($errors)){
$_SESSION['dob-month'] = isset($_POST['dob-month']) ? $_POST['dob-month'] : null;
$_SESSION['dob-day'] = isset($_POST['dob-day']) ? $_POST['dob-day'] : null;
$_SESSION['dob-year'] = isset($_POST['dob-year']) ? $_POST['dob-year'] : null;
$_SESSION['submit'] = isset($_POST['submit']) ? 1 : null;
}else{
$_SESSION['errors'] = $errors;
}
header("Location: /calculator/",TRUE,303);
}

This is how the sessions are set to variables in the function that is called on the page:

if (isset($_SESSION['dob-month'])||isset($_SESSION['dob-day'])||isset($_SESSION['dob-year'])||isset($_SESSION['submit'])||isset($_SESSION['errors'])){

$month = isset($_SESSION['dob-month']) ? $_SESSION['dob-month'] : null;
$day = isset($_SESSION['dob-day']) ? $_SESSION['dob-day'] : null;
$year = isset($_SESSION['dob-year']) ? $_SESSION['dob-year'] : null;
$submit = isset($_SESSION['submit']) ? $_SESSION['submit'] : null;
$errors = isset($_SESSION['errors']) ? $_SESSION['errors'] : null;




    session_unset();
    session_destroy();
}

Everything is loaded on the same page and no errors are reported. If I comment out the redirect line everything works as intended, and the sessions do pass along the variables. Otherwise a var_dump has shown the redirect results in an empty session array.

Edited by moobs
Link to comment
Share on other sites

SOLVED!!

 

The problem was with how I started the session in wordpress. Even though it was started before any HTML was parsed I still had to pass it through as an initializing function in functions.php. 1 just sets the priority.

 

add_action('init', 'myStartSession', 1);
function myStartSession() {
    if(!session_id()) {
        session_start();
    }
}
Link to comment
Share on other sites

So where is the code that we've been looking at?

 

I assumed it was in your functions.php file; you can start the session there just fine without having to call a function on the init hook. Just put the session_start() call at the top of functions.php after the direct access check and everything should work fine across all browsers.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.