Forum Moderators: coopster
In the one page form, that cats() array is used to make alterations to a couple DB tables on submission. But since I'm splitting the form up, I need to preserve that array value throughout the other 2 forms. I need the array available for submission or, should the user click back to the first form, to re-fill out the checkboxes.
My problem has been with passing the array value between forms. I've been POSTing the data from one form into hidden fields in the others, so that each form carries all the data entered so far. Unfortunately, when I attempt to put $cats into a hidden form field, the resulting form field contains only "Array".
So I tried taking the $cats array and serializing it into a string, then storing that string in the hidden form feild, but whenever I try to unserialize that string it gives me an error -- "error at byte 9 of 34bytes", something like that -- and fails to give me back my array.
So I've thought of a couple other ways to handle passing this array around, and wondered if anyone would mind giving me some insight into which one they think would be most efficient/secure/stable.
One, use the $cats array in each form to rebuild the checkboxes, but set them to display:none in the CSS so users can't tamper with them outside of the first page. This would be easy to accomplish, but it seems very 'hackish' to me.
Two, use SESSIONS to store the data as users enter it into the form. I know right next to nothing about using sessions, so I don't know if the $_SESSION variable is allowed/capable of holding a great deal of information...? If you think this would be a good way to handle passing these variables around, would you mind pointing me toward any good info you know of on using SESSIONS?
If anyone has any suggestions or recommendations, it would be greatly appreciated. Thanks!
cEM
something like: $nr_cats = count($_POST['cats']); //(or $_GET, depending on what you use)
next use a loop
for ($i=0; $i<$nr_cats; $i++){ //while $i < nr of occurences
$string= $_POST['cats'][$i];
//query here..whatever you need...use $string...dont forget to sanitize :p
$result = mysql_query($query) or die ("Error in query: $query " . mysql_error());
}
Sessions aren't really so scary as they sometimes sound. When you first want to populate your session, you can just do
$_SESSION['cats'] = $_GET['cats'];. Or better,
$_SESSION['cats'] = get_magic_quotes_gpc()? array_map('strip_slashes', $_GET['cats']) : $cats;
will strip the slashes for you first if you need to (be sure to use htmlspecialchars when outputting for security). session_start();and
$cats = $_SESSION['cats'];
If you want to serialize, this could be a pain - it'll give you lots of single quotes - and once it's passed via HTML, if you have magic_gpc_quotes() on, you'd have to stripslashes() it first, since this adds slashes to quoted stuff. I'm not sure how interoperable stripslashes() and serialize() would be - it could be that stripslashes() would also strip some of the slashes that serialize() had added, though I'd guess that this probably wouldn't happen and that everything would get properly escaped with backslashes for these to work ok together.
But what you could do if the two don't seem to jive is to base64encode() the string you get with serialize(), put that into a hidden field of your HTML, and base64decode it and unserialize it on the other end. base64encode will put it into a form that'll pass through HTML forms without a problem. Make sure when you deploy you have errors off or you use @base64decode() and @unserialize() to suppress errors since skriptkiddie users could change this to something else that would yield an error message.
instead of making all those checkboxes that can't be altered, just do the same thing with hidden input fields
mincklerstraat, that's a great idea. Thank you.
Part of me would rather go the extra step and figure out Sessions, though. It seems to me that sessions would be the right way to accomplish "saving" all the data across several forms prior to submission.
So here's a session question: I fill out form1 and POST it to the script. In the recieving script, I empty $_POST into $_SESSION, and that data will now be stored in the $_SESSION superglobal. I can pull out any values I need for form2, or leave the values I don't need right where they are, right? When I then POST form2, it runs through the same script, taking all the $_POST values from form2 and putting them into the $_SESSION superglobal.
Does $_SESSION now contain all of my data from form1 and form2?
If I then go back to form1 and change something, then POST form1 again to the script that copies $_POST into $_SESSION, does it overwrite the data stored in $_SESSION, or create a new index?
For instance:
Say form1 had these fields:
<input type="text" name="firstName" />
<input type="text" name="lastName" />
<input type="checkbox" name="cats[]" value="short" />
<input type="checkbox" name="cats[]" value="happy" />
<input type="checkbox" name="cats[]" value="rodent" />
I enter values and submit it, copy $_POST to $_SESSION and now basically have...
$_SESSION['firstName'] = 'Micey';
$_SESSION['lastName'] = 'Mouse';
$_SESSION['cats'] = array('short','happy','rodent');
Now I am in form2, which has these fields...
<input type="text" name="spouseFirstName" />
<input type="text" name="spouseLastName" />
I fill out and submit that and copy $_POST into $_SESSION. $_SESSION should now have the following values...
$_SESSION['firstName'] = 'Micey';
$_SESSION['lastName'] = 'Mouse';
$_SESSION['cats'] = array('short','happy','rodent');
$_SESSION['spouseFirstName'] = 'Minnie';
$_SESSION['spouseLastName'] = 'Mouse';
Now I go back to form1 and uncheck the checkbox for "happy". I also correct the mispelling of "Micey". Then I submit it and copy $_POST to $_SESSION and ...? Does $_SESSION now have these values...
$_SESSION['firstName'] = 'Mickey';
$_SESSION['lastName'] = 'Mouse';
$_SESSION['cats'] = array('short','rodent');
$_SESSION['spouseFirstName'] = 'Minnie';
$_SESSION['spouseLastName'] = 'Mouse';
...?
Sorry for the length and redundancy. I really appreciate you taking the time to help.
cEM
Does $_SESSION now have these values...
I keep on forgetting about checkbox behavior when it's not checked, whether it returns an empty var or just nothing, but the question as to whether you get a short, happy rodent as to a short rodent would depend on what value your $_GET array is returning. If you just simply copy $_POST into $_SESSION, yeah, it will just rewrite everything, and re-set the array to a shorter array if it's a shorter array that comes through. At any rate, you'll be able to forget about happy. I'd advise against this course of action and try to find a way to keep happy in the array if at all possible. You want happy, even if it's only for the sake of a short rodent.
I use this in at least 20 scripts on my site....and it makes everything after:
My problem has been with passing the array value between forms. I've been POSTing the data from one form into hidden fields in the others, so that each form carries all the data entered so far. Unfortunately, when I attempt to put $cats into a hidden form field, the resulting form field contains only "Array".
in your initial post meaningless and redundant :)
You want happy, even if it's only for the sake of a short rodent.
It was only after Mickey entered the information about his wife that he realized 'happy' was a bit too optimistic. ;)
Okay. I think I'm set to give this a try with sessions. Thanks for the tips. I may be back.
dont be stubborn and not try
That's not me being stubborn; it's me being stupid. I didn't understand half of what your code was doing!
Upon reflection, it seems that you are looping through all of the checked checkboxes on the page and building a string of their numerical values...?
Question: Since $_POST only carries the values of the checked checkboxes, won't it only cycle through those? So if there are threee checkboxes, and 1 and 3 are checked, the loop will only pick up 2 values. However, since there are only 2, won't the values stored in the string be '1' and '2', instead of '1' and '3'?
Also, once stored in a string in the hidden form field, the string will have to be split back up into array values when needed, which isn't too different from the problem I had with serializing the data. Is there a simple way to convert that string back to an array?
Of course, my real question is which method would be the best to use. Is passing values around via $_POST better than using sessions, or vice versa? Which is more secure?
cEM
That's not me being stubborn; it's me being stupid. I didn't understand half of what your code was doing!
fair enough, sorry :)
Upon reflection, it seems that you are looping through all of the checked checkboxes on the page and building a string of their numerical values...?
if you have assigned numerical values then yes. I assumed you'd use it like:
<input type="checkbox" name="cats[]" value"some_value">
<input type="checkbox" name="cats[]" value"some_other_value">
Question: Since $_POST only carries the values of the checked checkboxes, won't it only cycle through those? So if there are threee checkboxes, and 1 and 3 are checked, the loop will only pick up 2 values.
yes, you dont need the rest anyway, or you wouldnt be using checkboxes here (correct me if I am wrong)
However, since there are only 2, won't the values stored in the string be '1' and '2', instead of '1' and '3'?
yes, this is why you need to count the lenght of the 'cats' array. you name the checkboxes "cats[]" instead of "cats" so that you imply so to speak, that it is an (possibly) recurring element in the HTML, no matter the type of input, be it an hidden field, or a checkbox. Because you do not know how many checkboxes the user has checked, you need to count the lenght of the array in question, in your case the array cats. The PHP fucntion count() will do this for you --> [nl3.php.net...]
after you have determined the lenght of the array, or the amount of occurences if you prefer to think of it this way, you can specify a action. Because $_POST['cats'] is an array, because we made it an array when we put the brackets after the elements name (only if user select more then one checkbox), you cannot use $_POST['array'] (as this will just say 'Array'), but you need to use $_POST['cats'][0] for the first occurence, $_POST['cats'][1] for the second and so on and so on, to be able to use the passed values in a query, or in your case, a hidden field.
this is all done in the loops I posted above :)
Also, once stored in a string in the hidden form field, the string will have to be split back up into array values when needed, which isn't too different from the problem I had with serializing the data. Is there a simple way to convert that string back to an array?
yes, like I stated above, when specifying a HTML element's name with [] behind it, you 'let the form know' that it could be a possibly recurring element. So on the first page you have checkboxes names as "cats[]" and their values are echoed out on the next page in a hidden field with the same name "cats[]", enabling you to pass multiple values to yet another page as an array.
On this second page perhaps there are another set of checkboxes with another name, maybe "sex[]" (I like the word, sue me :p ), which values on the third page should be echoed out in also hidden fields with name "sex[]" (ofc. you could use something else, but this is very confusing), along with the hidden field array "cats[]"
hence, the loops which generate the hidden inputs for the length of the array, determined with count().
Of course, my real question is which method would be the best to use. Is passing values around via $_POST better than using sessions, or vice versa? Which is more secure?
my personal opinion is that hidden fields are far more intuitive and less cumbersome, but I guess that perhaps is a matter of personal preference.
this may all seem very odd to you, but once you understand its logic, you will create complicated forms and pass along values and arrays in minutes, not days, as you most likely are now :)
above we have to checkboxes...in my example they are both checked...at least we assume them to be for now :)
now, we count the lenght:
$nr_cats = count($_POST['cats']);//2, because 2 were checked
for ($i=0; $i<$nr_cats; $i++){ //while $i < nr of occurences, incerement $i with 1, it starts with '0', so the second and last occurence will be '1'?>
<input type="hidden" name="cats[]" value="<? echo $_POST['cats'][$i];?>">
<? }
(the above is basically the same like using:
value="<? echo $_POST['cats'][0];?>"
value="<? echo $_POST['cats'][1];?>)
the loop will echo the following html:
<input type="hidden" name="cats[]" value="some_value">
<input type="hidden" name="cats[]" value="some_other_value">
hope I make sense :)