Whats the best was of doing this?
Sessions? How can I take all my variables defined on 1 page and send them over to another.
I read using serialize convert the HTTP_POST_VARS to a string, and then pass that (using a hidden form/input?) and use unserialize on the other PHP page to get the variables back.
Also I saw someone just use something like:
<?php
foreach($HTTP_POST_VARS as $key => $val) {
?>
<input type="hidden" name="<?php echo $key; ?>" value="<?php echo $val; ?>">
<?php
}
?>
Which seems ugly and asking for trouble.
Basically this is the run down of what I am trying to do:
The user fills out a form and then submits the form with all the information thats required. A second page intercepts all the HTTP_POST_VARS and then defines more variables. The user is asked if the information is correct and asked if they would like to submit all information. So far I have gotten this far. Now I want a button/link where the user clicks it and then it sends all the information page 2 has to another page where it finally runs the code to process all the information. (MYSQL, EMAILS, etc)
My ideal solution would be able to define something like onclick where I can just run a PHP function at whim, but that doesn't exist. One thing is I want to make sure information thats posted/pushed/whatever to page3 (processing) that its legit and actually comes from page2 (confirmation)...I don't want people just randomly making HTTP POSTs and having it validate. I was thinking of running some kind of MD5 stuff with a secret key to validate.
Does anyone have an elegant solution of a form where you have PART 1 ( filling out), PART 2 (confirmation to user) and PART 3 (processing all information from PART 2).
I would store the values in a session variable after the initial submission and then use them accordingly after confirmation/validation:
<?php
/////////////////////////////////
// STEP 1 - Initial Form Display
/////////////////////////////////
session_start();
echo '<form>';
echo '<input type="text" name="usr_name" />';
echo '<input type="text" name="usr_phone" />';
echo '<input type="text" name="invalid_field" />';
echo '<input type="submit" name="submit" value="Submit" />';
echo '</form>';
/////////////////////////////////
// STEP 2 - Confirmation Page
/////////////////////////////////
// change this by your global of choice ($_POST, $_GET, $_REQUEST)
$input_source &= $_GET;
// create an array of all input fields that start with 'usr_'
$input_fields = #preg_grep( '#^usr_[a-z]+#i', array_keys( $input_source ) );
if( !empty( $input_fields ) )
{
// store all valid input fields in the session
$_SESSION['input_values'] = array();
foreach( $input_fields as $key )
{
$_SESSION['input_values'][$key] = $input_source[$key];
}
// create a checksum from the user's IP address and all input values (for false sense of security ^_^)
$_SESSION['input_checksum'] = md5( $_SERVER['REMOTE_ADDR'] . '|' . join( '', $_SESSION['input_values'] ) );
// logic for data validation and confirmation HTML goes here...
}
/////////////////////////////////
// STEP 3 - Final Validation
/////////////////////////////////
// check for the existence of the session values from step 2
if( !empty( $_SESSION['input_values'] ) && !empty( $_SESSION['input_checksum'] ) )
{
// create comparison checksum for validation purposes
$_comp_checksum = md5( $_SERVER['REMOTE_ADDR'] . '|' . join( '', $_SESSION['input_values'] ) );
// check session and comparisson checksums
if( $_SESSION['input_checksum'] == $_comp_checksum )
{
// confirmation/validation looks good, proceed...
}
}
?>
I generally just put everything into Session variables AFTER I have validated the information. I have always had pretty good luck with that and since there is generally not a lot of user information like you are talking about the overhead really isn't all that bad. Now, if you are talking A LOT of data then you may want to consider a different method.
Like I said, this may not be the most elegant solution but it will certainly work.
How about to share your needed information into the session after page1?
Well here you got everything you need:
php - session reference
Ugly and asking for trouble? I think you're on to something.
Ideally, you could store previously-entered data in session state, which stores the data on the server.
Alternatively, if the state needs to be stored in the browser page, you can use the method you mentioned, or you can do something a bit more like Microsoft's "view state" variable.
Essentially, you serialize your data, perhaps encrypt and/or sign the result, and then base64 encode the whole lump and stick the result in hidden variable on the page. The advantage of doing it this way include (a) not polluting your namespace with old variable names, (b) not confusing form-filling addons and utilities, (c) tamper-resistant variable storage (esp. if encrypted or signed).
Related
Sorry if I'm duplicating threads here, but I wasn't able to find an answer to this anywhere else on StackOverflow.
Basically what I'm trying to do is make a list in which variables entered in a form by a user can be kept. At the moment, I have the code which makes this possible, and functional, however the variables entered in the form only appear on the list after the user hits submit... As soon as I refresh the page or go to the page from somewhere else, the variables disappear. Is there any way I can stop this from happening?
Edit: here are the codes:
//Page 1
<?php
session_start();
$entries = array(
0 => $_POST['signup_username'],
1 => $_POST['signup_email'],
2 => $_POST['signup_city']);
$entries_unique = array_unique($entries);
$entries_unique_values = array_values($entries_unique);
echo "<a href='Page 2'>Link</a>";
$_SESSION['entries_unique_values'] = $entries_unique_values;
?>
//Page2
<?php
session_start();
$entries_unique_values = $_SESSION['entries_unique_values'];
foreach($entries_unique_values as $key => $value) {
$ValueReplace = $value;
echo "<br /><a href='http://example.com/members/?s=$ValueReplace'>" . $value . "</a><br/>";
}
?>
Your question is really quite vague. the answer depends on how much data you have to store, and fopr how long you need it to exsist.
By variable I assume you mean data the user has entered and that you want to put into a variable.
I also presume that the list of variables is created by php when the form is submitted.
Php will only create the variable list when the form is submitted as php is done entirely on the server, therefore you will not have or see the variables until the form is submitted.
if you wanted to be able to see the list as it is being created you could use javascript then once you have you php variables the javascript list isn't necesary.
each time you request a php page wheather it is the same one or not the server generates a totally new page, meaning all unhardcoded variables from previous pages will be lost unless you continually post the variables around the pages the server will have no memory of them.
You have a few viable options.
) keep passing the user created variables in POST or GET requests so each page has the necesary info to work with. Depending on the situation it might or might not be a good idea. If the data only needs to exsits for one or two pages then it is ok, but bad if you need the data to be accessable from any page on your web.
2.) start a session and store the variables in a session. Good if the data only needs to be around while the user is connected to the site. but will be lost if user close window or after a time.
3.) place a cookie. not a good idea but ok for simple data.
4.) create a mysql database and drop the variable info in there. great for permanent data. this is how i always complex user data.
just a few ideas for you to look into as it is difficult to see what you really mean. good luck.
use PHP session or store variable values in Cookies via JS or using PHP. It would be nice if you show your working codes :)
Your idea is fine, however you just need to add a little condition to your Page 1 that only set your SESSION values when POST is made, that way it will keep the values even if you refresh. Otherwise when you visit the page without a POST those values will be overwritten by blank values, which is what you are seeing now. You can modify it like
<?php
session_start();
if(isset($_POST["signup_username"]))
{
$entries = array(
0 => $_POST['signup_username'],
1 => $_POST['signup_email'],
2 => $_POST['signup_city']);
$entries_unique = array_unique($entries);
$entries_unique_values = array_values($entries_unique);
$_SESSION['entries_unique_values'] = $entries_unique_values;
}
echo "<a href='http://localhost/Calculator/form2.1.php'>Link</a>";
?>
You could use JavaScript and HTML5 local storage.
Here is what I would do in JavaScript. Is there any way to do it in php?
I am working on a project that needs this functionality but cannot use JavaScript.
setInterval ( "checkHistory()", 1000 );
function checkHistory() {
if (oldHistLength != history.length) {
removegateway();
oldHistLength = history.length;
}
}
Sorry to say that it's not possible to do that using PHP. Your only option is to use JavaScript somewhere.
You can however achieve what I believe you're trying to do with another technique - PHP Sessions and Request URIs.
This involves storing the user's accessed URLs into a variable (or you could use MySQL) which can be referenced anywhere on the website within that current session.
Here's an (untested) example:
<?php
session_start();
// Retrieve/create the current list
if( isset($_SESSION['history']) ) {
$history = $_SESSION['history'];
} else {
$history = new array();
}
// Add the current URL to the history array
array_push($history, $_SERVER['REQUEST_URI']);
// Do anything else you want to here
// Store the array again
$_SESSION['history'] = $history;
?>
In your code, you can keep an array containing the values of $_SERVER['php_self'], serialize() it, and store it in a session variable. This may not be sufficient for what you are trying to do though. I'm not sure what removegateway() does, but is this code attempting to prevent the back button from being used?
If you prevent the pages from being cached, you might be able to compare the second to the last value in your array to the current page, and if they match, you detected a back button. This would only be possible if there's no way to go back to the previous page on the front end.
Preventing the back button is generally considered a Bad Thing, so it might be better to reconsider the way you are doing things and come up with a better solution.
I have a an array I want, whenenever i submit my form the post value get inserted into that array, every time with new incremented index..
How can I do that? And yes submited page is redirected to itself...
In PHP:
$arr[] = value;
$arr[] = other value;
In HTML:
<input type="text" name="arr[]" />
<input type="text" name="arr[]" />
You could solve this using the session-variables. This way the data won't be overridden. Here's an example:
$_SESSION['formdata'][] = $_POST['value1'];
$_SESSION['formdata'][] = $_POST['value2'];
After you reload the script the data will still be available an pushing other values into the array won't override the old ones. You just do it again:
$_SESSION['formdata'][] = $_POST['value3'];
$_SESSION['formdata'][] = $_POST['value4'];
Calling the $_SESSION['formdata']-Array you now have all 4 values stored in there.
** EDIT **
I am finally home, and as promised I'm offering another solution using cookies, since sessions don't work for you, as we've already discussed. So here we go...
First of all we need to think of the way we want to name the cookie. I would suggest we would do this by ip-address and any suffix, to ensure, that it is really the user who has already filled, the former forms.
So we could go like this:
$dataArray[] = $_POST['value1'];
$dataArray[] = $_POST['value2'];
Then we need to store the data into an cookie. We do this by serializing the array, since we don't want to save hundreds of cookies. This would work like this:
$cookievalue = serialize($dataArray);
// Here we actually generate a cookiename in the format of "IP_formdata"
setcookie($_SERVER['REMOTE_ADDR'] . '_formdata', $cookievalue);
So far so good. Within the next form we retrieve the cookie-data and unserialize the data, so we can extend this array:
$dataArray = unserialize($_COOKIE[$_SERVER['REMOTE_ADDR'] . '_formdata');
Now we can add other values to the array from the second form:
$dataArray[] = $_POST['value3'];
$dataArray[] = $_POST['value4'];
After all additional values have been put into this array we serialize it again and store it into the again again:
$cookievalue = serialize($dataArray);
setcookie($_SERVER['REMOTE_ADDR'] . '_formdata', $cookievalue);
Now we can repeat this steps for all further forms. Just remember that if you want to work with the data you first have to unserialize the data and store it into an array.
And don't forget as I have already stated in the comments: The user can turn off cookies, then the whole thing won't work. You could also add some additional checks to verify that this is the correct user or something. I haven't tested the code, but I think it should work in a way like this and I hope I could help you or at least give you a hint :)
I'm a beginner in PHP.
What I'm trying to do is stop Post Data coming from another webpage.
The problem I am having is let's say someone copies my form and pastes it in their website. I want to be able to stop that Post Data from running the script on my email form.
How can I do this? Let me know if I'm not being clear enough.
My PHP Contact form runs on one page with conditional statements. i.e. if data checks out, submit.
"accepted answer" has security holes. Instead, you should use more secure methods. A simple example:
Step 1: Disable framing of the page (.php), where the form is generated, in the top add:
header('X-Frame-Options: Deny');
Step 2: (important part ! ): In order to avoid XSS and 3rd party exploits, you should create a expirable validation.
For example:
ASP.NET builtin forms use dynamic input csrf (example value: gtlkjh29f9ewduh024cfvefb )
WordPress builtin forms use dynamic input nonce (example value: 340297658942346 )
So, if you are on a custom platform, which doesn't have built-in temporary token validation methods, then implement your approach. A simple concept:
<?php
$secret_key = 'fjd3vkuw#KURefg'; //change this
$encrypted_value = Cryptor::encrypt( time(), $_SERVER['REMOTE_ADDR'] . $secret_key);
?>
<form>
...
...
<input value="<?php echo $encrypted_value;?>" name="temp_random" type="hidden" />
</form>
(Cryptor code is here )
on submission, check:
if(!empty($_POST)){
// If REFERRER is empty, or it's NOT YOUR HOST, then STOP it
if( !isset($_SERVER['HTTP_REFERRER']) || parse_url($_SERVER['HTTP_REFERRER'])['host'] != $_SERVER['HTTP_HOST'] ){
exit("Not allowed - Unknown host request! ");
}
// Now, check if valid
if ( Cryptor::decrypt( $_POST['temp_random'], $_SERVER['REMOTE_ADDR'] . $secret_key) < time() - 60* 15 ) {
exit("Not allowed - invalid attempt! ");
}
...........................................
... Now, you can execute your code here ...
...........................................
}
You're trying to prevent CSRF - Cross-Site Request Forgery. Jeff himself has a blog article about this.
True XSRF Prevention requires three parts:
Hidden Input Fields, to prevent someone from just snatching the form and embedding it
Timechecking within an epsilon of the form being generated, otherwise someone can generate a valid form once and use the token (depending on impementation/how it's stored)
Cookies: this is to prevent a malicious server from pretending it's a client, and performing a man-in-the-middle attack
$_SERVER['HTTP_Referrer'] would be nice but it isn't reliable. You could use a hidden form field that MD5's something and then you check it on the other side.
In the form:
<?
$password = "mypass"; //change to something only you know
$hash = md5($password . $_SERVER['REMOTE_ADDR']);
echo "<input type=\"hidden\" name=\"iphash\" value=\"$hash\"/>";
?>
When you are checking:
$password = "mypass"; //same as above
if ($_POST['iphash'] == md5($password . $_SERVER['REMOTE_ADDR'])) {
//fine
}
else {
//error
}
If you're looking for a quick-and-dirty approach, you can check the REFERER header.
If you really want to make sure that the form was fetched from your site though, you should generate a token each time the form is loaded and attach it to a session. A simple way to do this would be something like:
$_SESSION['formToken'] = sha1(microtime());
Then your form can have a hidden input:
<input type="hidden" name="token" value='<?=$_SESSION['formToken'];?>' />
and you can check that when deciding whether to process your form data.
Every user do signup and then obtain a login id.
Following is algorithm to prevent CSRF: -
1) $login_id = user login id (converted to a numeric id using mysql)
2) $a_secret_key = $_SERVER['UNIQUE_ID'];
3) $remote_addr = $_SERVER['REMOTE_ADDR'];
4) Request Date and Time -> A unique reference key -> $refkey
5) $_SESSION['secretkey'] = $_SERVER['UNIQUE_ID'];
Combine aforesaid 1 to 4 to create a json file, when transferring data to another page.
Then
echo "<input type=\"hidden\" name=\"refkey\" value=\"$refkey\"/>";
At receiver's end:-
Receiver page should check if
1) any json file with $refkey exists at server?
2) If $refkey exists, then check $login_id, $a_secret_key and $remote_addr exists and are correct.
There's a typo in the highest score answer. It should be $_SERVER['HTTP_REFERER'] instead of $_SERVER['HTTP_REFERRER'].
In Yahoo or Google and in many websites when you fill up a form and if your form has any errors it gets redirected to the same page.
Note that the data in the form remains as it is. I mean the data in the text fields remains the same.
I tried ‹form action="(same page here)" method="post or get"›. It gets redirected to the page, but the contents of the form gets cleared.
I want the data to be displayed.
You know how tiresome it will be for the user if he has to fill up the entire form once again if he just forgets to check the accept terms and conditions checkbox.
Need help!
You need to do this yourself. When the page gets posted you'll have access to all the form values the user entered via $POST['...']. You can then re-populate the form fields with this data.
Here is a modified version of what I use for very simple websites where I don't want/need an entire framework to get the job done.
function input($name, $options = array()) {
if(!isset($options['type'])) $options['type'] = 'text';
$options['name'] = $name;
if(isset($_POST[$name]) && $options['type'] != 'password') {
$options['value'] = htmlspecialchars($_POST[$name]);
}
$opts = array();
foreach($options as $key => $value) {
$opts[] = $key . '="' . $value . '"';
}
return '<input ' . implode(' ', $opts) . '/>';
}
(I have a few similar functions for <select> and <textarea> and so on)
When you're building fields you can do something like:
First Name: <?=input('first_name')?>
Last Name: <?=input('last_name')?>
Password: <?=input('password', array('type' => 'password'))?>
If you process your forms in the same page as the form itself, they will get auto filled if there are any errors. Most frameworks, though, do all of this for you (and in a much better way than the code above), I personally suggest CakePHP or CodeIgniter.
This is not done automatically. They get values from post / get and then assign the values the user typed to the template. What you see is html that was generated from the script that handled user values.
If you put your form and the form data processing in the same script, you can easily print out the data that has already been entered in the form, e.g.:
$valid = false;
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (isset($_POST['name']) && $_POST['name'] == 'Hugo') {
$valid = true;
} else {
echo '<p>Seriously, you have to enter "Hugo"!</p>';
}
// more data processing
if ($valid) {
echo '<p>Everything’s fine!</p>';
}
}
if (!$valid) {
echo '<form action="" method="post">';
echo '<p>Please enter "Hugo": <input type="text" name="name" value="', (isset($_POST['name']) ? htmlspecialchars($_POST['name']) : ''), '"></p>';
echo '<p><input type="submit"></p>';
echo '</form>';
}
Well this is not nice example but that’s how it works.
a lot of frameworks do this job for you, so dont waste your time doing this manually
You'll have to check the data within the same file, and if it is correct, then you redirect to the correct location. Then you can use the $_POST or $_GET information the user posted and he can fix the error(s).
You can use two approachs (they're not mutually exclusive):
Use JavaScript to help the user before he submits the form. That way, you save a roundtrip to the server.
What you asked for:
In the form, fill the value attributes of the fields with the data sent back from the server. For example: you send a field name, which you get as $_POST['name'] in PHP (assuming you used method='post'. If you send back the data and modify that field adding value='<?php $_POST['name']; ?> you should get your data back.
If you're using a template or framework system (I've incorporated the Smarty engine into several projects of mine), you can usually tweak the templates so they automatically fill fields with values if they detect that the $_POST[$variable] value corresponding to their field is set.
As for the passwords, as far as I understand it (I could be wrong): it's a convention that minimizes the amount of time that password is being sent over the wire, hence shrinking the window for anyone who may be sniffing to pick up on the text. It's just good practice to leave password fields blank, is all.