Forum Moderators: coopster
I have a form with dozens and dozens of vars which are then passed to database.php. That works fine.
But if I then reload database.php all the vars are lost!
Now I know I can use sessions or pass the vars via the url?var1=yyy etc. but that's not possible in this case due to there being dozens and dozens of vars.
If database.php can read the vars passed to it from another php script then why can't it read when passed to itself!
form.php
--------
form action = database.php
lots of check boxes, radio button, drop down lists etc.
Submit - calls database.php
database.php
------------
read vars and run database search based on vars e.g. SELECT * from database where var1 > 1 and var2 < 5 and var......... order by NAME
That works fine.
However, I then want to reload the page but this time sorting by CITY.
I put a link on the page:
<a href="database.php?sort=city">sort on city</a>
but doing that loses all the varx variables.
How do I get the varx variables to remain valid without sessions and without passing via url?
HTTP is "stateless" meaning that each time you access a page, the webserver has absolutely no idea whether you are the same person that just accessed the same page X seconds/minutes/hours/days ago. Using cookies, or passing variables via GET or POST, is a way to get around that and "maintain state".
>> How do I get the varx variables to remain valid without sessions and without passing via url?
GET, POST or COOKIES. No other way.
My point is that I can pass the vars to database.php via a form, but then if I reload database.php it doesn't remember the vars.
How come database.php can initially read the vars, but on a reload it can not?
Is the answer to have the sort link as a form submit rather than a href link?
[w3.org...]
I have 116 variables which are transfered to the database.php script. No sessions are used, no URL posting the submit button is pressed and database.php reads all the variables.
The problem is when I try to reload the datatbase.php script with a new scenario such as sort by city instead of name.
I don't want to use sessions. It's not that it's too much hassle to code it - it just seems ridiculous to put 116 variables into sessions. I shudder to think of the memory which will be utilised.
Here's one way around it. Binaryise (?) a URL string.
e.g. if I had checkboxes of var1 (Y/N ticked or not) var2 (Y/N).... var116 (Y/N) then I could construct:
database.php?binaryised_vars=111101010101010000.... etc.
But the form contains a mix of checkboxes, radio buttons and numeric input boxes so it's not practical.
I did think of compressing the data into a zip string.
e.g. use the 1111010101 kind of binary switches and then tag on set field lengths for the radio buttons and input boxes. 1111010100365012ACD etc. where 0365, 012, ACD are set codes. Just need to zip / compress them and call database.php?encoded_data=7FA1B....C90
This is not the way to do it though. The problem is that php CAN read data from a form, like magically passed to it via global vars. Why can it not read the same vars if the script is called twice?
Here's another great example (and I'll seriously give up this thread if no one agrees with me).
Use the form and click submit to pass vars to a script.
Keep pressing Reload / Refresh and the SAME DATA is displayed! If php can not rememeber data passed to it then why does it still keep refreshing with the same data?
You can even edit the script to say, change the font of the data, and then refresh and you get the same data with a new font!
Why can you not reload a page via a link and keep the same vars data?
are you against setting cookies?
something like this will put all the variables obtained by POST in one cookie
if(count($_POST)) {
foreach($_POST as $n => $v){
$cookie .= "\$".$n."=".$v."&";
}
setcookie("myCookie",$cookie);
}
this will get them out of the cookie
if($_COOKIE['myCookie']){
$readcookie = $_COOKIE['myCookie'];
$vars = explode("&",$readcookie);
foreach($vars as $n => $v){
$s = explode("=",$v);
$b="";
for($i=1;$i<=count($s)-1;$i++){
$b .= $s[$i];
}
${$s[0]} = $b;
}
}
the data comes in, you deal with it, the data goes out. the script completes.?>
once it's in the user's browser, it's gone.
AND WAAAAHT?! fonts change but data stays the same!?! (I belly-laughed dude, I really did, thanks for that, I once was that ignorant of these things) YES! of course they do! every time you click refresh, your browser re-sends the same form data! think about it. that's why it's called a 'post' variable. you posted it. you don't have to leave this thread, but it's unlikely anyone will agree with you on that.
And what's wrong with sessions? a few short lines of code could handle the whole thing. the php manual has some excellent examples, there's also one above.
once you have a "state" to work with, (that is; you have identified a unique user's browser), then you can do anything with the their unique data, whatever you like, but first you need to identifiy the user's browser, and you need somewhere to store their data set. a session allows you to easily achieve both. the alternative is one big pile of messy JavaScript, don't even go there.
you don't even need real "cookies" either, temporary "session" cookies can do the whole lot, nothing is stored at the user's end, and when they close their browser the session is gone (by default, you can alter the time). I put together a wee demonstration for you. hopefullly this will make things clearer.
<?php
/*
the first if() section grabs the user's $_post data and "serializes" the array into a string, which will become our current session data set (just a simple array here), the second if() section pulls the data set back from the server's session file, unserializes it, and creates our $fruit array. both arrays are printed out for your enjoyment.
save the code and load it in a browser. at that point, a session is established.
enter some values for the fruit - I have thoughtfully provided three common fruit strings.
hit "do it".
once new values have been sent (post(ed)) to the server, the script "serializes" the array into a string, and the web server stores those values server-side, in its session token (in /var/tmp or whatever); for our example, the file would most likely read..
user_data¦s:66:"a:3:{s:1:"a";s:5:"apple";s:1:"b";s:6:"orange";s:1:"c";s:4:"kiwi";}";
but we don't need to know the details, only that you can "serialize" almost anything, especially arrays, store and transmit that data as a simple string so you can store the string wherever, send it, and then "unserialize" it again at the other end, recreate your data, even really complicated data, even dozens and dozens of multi-dimensional arrays filled with complicated data, no problem. pretty nifty.
if you then hit [refresh] (even again and again!) you'll just keep sending the same three fruits.
post post post!
if you click in your address bar, and hit [enter] (get the page afresh, without sending $_post variables), the script will (in the absence of any new 'user_data' $_post variables) fetch the old array from the session data, and you will see the $_post array printout is empty (no data was posted this time, only commands, perhaps), but, as a session has already been established, your $fruits array is still there, and the second array report shows all your fruits, recreated from the serialized array.
open a new tab in your bowser, and your fruits are still there! they are stored on the server, all the browser is supplying is a unique session ID, so the server knows which session file to use. And when the browser quits, it will be no more than a memory, food for the php garbage collector.
have fun!
;o)
(or
*/
$fruits = array();
session_start();
if(isset($_POST['user_data'])) {
$post_data = serialize($_POST['user_data']);
$_SESSION['user_data'] = $post_data;
}
if(isset($_SESSION['user_data'])) {
$fruits = unserialize($_SESSION['user_data']);
}
/*
then you'd go on to process your other $_post vars, that "sort by date" button, etc.
here I'll just do a wee test form instead..
*/
echo '<br><pre>$_post: ',print_r($_POST),'<br><br>$fruits: ',print_r($fruits),'</pre><br>';
echo '
<form name="a_form" method=post action="',$_SERVER['PHP_SELF'],'">
fruit a <input type="text" name="user_data[a]" size=30 value="apple"><br>
fruit b <input type="text" name="user_data[b]" size=30 value="orange"><br>
fruit b <input type="text" name="user_data[c]" size=30 value="kiwi"><br>
<input type="submit" value="do it">
</form>';
?>
okay, in trying to make it readable, I think I made it worse; in fact, it's clearer to read simply like this (been a long night)..
session_start();
if(isset($_POST['user_data'])) {
$_SESSION['user_data'] = serialize($_POST['user_data']);
}
if(isset($_SESSION['user_data'])) {
$fruits = unserialize($_SESSION['user_data']);
}
which is the whole thing, really.
;o)
(or
ps.. at least in the preview, the pre tag doesn't work properly here (kills tabs). if the code tags worked I would never have known that. heheh
[edited by: corz at 9:22 am (utc) on May 30, 2004]
Yes I am anti cookies / sessions on this one. As I say, there are 116 variables to be cookied / sessioned. To me that seems hell of a lot and totally inefficient for a php script.
(Sidenote I use mm rather than /tmp/ hard writing to disk. We're talking reports which have to be done in an instant!)
I accept now the limitations of php in that reloading the script loses (but it's still there if you refresh) var data.
Let me put this another way to you then.
Let's say that I don't want the vars to change. They can stay exactly the same when the script is reloaded. All I want to do is to change the "order by" of a select by reloading the script.
form set vars -> call database.php -> display report
user requires report to be ordered DESC instead, click something, redisplay report with select .... order by CITY DESC.
Is that possible in anyway?
Why don't you put the form on the same page as you collect and parse the data (in this case database.php)? That way you can populate the form fields with the posted data.
You can also do it the hidden way, put a hidden field on the database.php and populate it with the posted data from form.php. That way, the data will be re-posted and parsed everytime you hit refresh.
I wouldnt want the php script to remember all my vars, especially not the posted ones.
form.php
<form.....
116 variables...
database.php
$vars_passed = addslashes(serialize($_POST));
What that does is to put the whole data (all 116 vars) into a long string called $vars_passed.
Now within the database.php script I can have something like:
<a href="database.php?vars_passed=$vars_passed?sort=CITY">sort by city</A>
<a href="database.php?vars_passed=$vars_passed?sort=STATE">sort by state</A>
obviously the start of database.php needs to know if the data came straight from the form, or via the url
if(unset($vars_passed)){
//do nothing as this is a first pass straight from the form
} else {
$varsdata = unserialize($vars_passed);
extract($varsdata, EXTR_OVERWRITE);
}
Now how does that sound?
I think the "database.php?vars_passed=$vars_passed" may be too long though as serialising creates big string.
How can I compress it? base_64 encoding seems to increase the size.
Precicely, you could use any old place for this, a MySQL database, for example. I suggested the session itself because it's a no-brainer to implement, and kills two birds with one stone. But crucially, you also need a way to link the browser with their data.
as Bonusbana and I said.. use the same phpfile for both functions
this line..
$vars_passed = addslashes(serialize($_POST));
looks like it will turn a perfectly good serialized array into gibberish.
and then..
<a href="database.php?vars_passed=$vars_passed?sort=CITY">sort by city</A>
firstly, of course, you mean &sort=CITY></a>, secondly, NO! we are using $_post variables. But the passing multiple variables; yes, that's exactly what I meant when I said ..
/*
then you'd go on to process your other $_post vars, that "sort by date" button, etc.
*/
reaplce "sort by date" with whatever other data manupilation you want to offer the user.
The serialised string itself could be 10MB long, 100MB! (though that would be one helluva $_POST!) but the user still won't SEE any of it in their address bar, that's only $_GET variables. to the user, the url is always just plain old "page.php".
$_POST variables are effectively invisible to the user. which is why they are used for large text input areas, imagine some of these posts here at webmasterworld as URLs! This is why, when you refresh a posted page, most good browsers will warn you that you are about to resend post data, all mine do. see, just as well most people don't read these kinds of notices before thoughltlessly clicking them, else many tech support workes would be immediately unemployed.
the rest of your code simply isn't php, not without some work. and you still haven't stored the variables anywhere, for the user's next reload. How will the script know what data set to sort by CITY? unless you want to send all 116 variables back to the user in your generated HTML output! and then have them submit them all back again with with each and every sort request! sheer madness.
see those five lines I posted at the top of this page, they do it all, and they also work. the only difference being the "$fruit", you can call your new array whatever you like, and 116 items is nothing for PHP, tiny, minute, etc. One of PHP' great strengths its the ability to work with HUGE, and I really do mean HUGE strings. Essentially (and this sounds like a quote from the php manual.. "you never have to worry about big strings")
I guarantee the web server can pull that string from the session file in a fraction of the time it would take a user to post the whole lot back to your server. a small fraction. and anyway, why waste the bandwidth?
using MySQL to store the session user data would likely be faster still, but I haven't played around with that.
bottom line: unless you want URL's the length of the War and Peace, or a big fun afternoon (make that three) screwing about with (possibly user-disabled) JavaScripting; you will need to create a session.
all the best..
;o)
(or
Problem: php loses form variables on subsequent page reloads
Solution:
1. The best solution is to have the report on the same page as the form. This is where you contstruct code flow to detect what state the page is in.
if ($form_filled_in <> 'Y') {
<form action....
$form_filled_in = 'Y';
} else {
//form is filled in so generate the report.
select * .....
<a href="....
//can put in extra stuff here whereby a form reload will remember the initial form vars.
}
2. Store the $_POST var as this contains all the vars passed to the script.
In the form script you would have:
$vars_passed = addslashes(serialize($_POST));
In the database or report script you would have:
if(unset($vars_passed)){
//do nothing as this is a first pass straight from the form
} else {
$varsdata = unserialize($vars_passed);
extract($varsdata, EXTR_OVERWRITE);
}
3. If you are not using many vars then you can just pass the vars to the script via the URL database.php?var1=$var1&var2=$var2...
4. If you don't want to pass via the URL you can use sessions. See the earlier threads.
For situations where you have many variables 1) is probably the best.
If you have many variables and use shared scripts (many different forms accessing one database.php script) then 2) is probably the best.
3. Is the simplest but not the neatest.
4. Is the neatest solution but requires a bit of extra coding. Beware of storing session data onto disk as this wears out the disk and slows down reports. Far better to use memory for saving sessions.