Retaining $_GET data across pages

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

Post Reply
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Retaining $_GET data across pages

Post by jayshields »

Yo,

Didn't know if this would require client side or server side attention so I took a stab at this forum, because I think I might have to knock up some completely crap hidden input type work around or maybe use sessions.

I'm currently making a page which parses results from a MySQL table. With a load of HTML form elements at the top you can define the results, you can sort, search and choose how many results to display. This works fine and dandy, and for the sort and record display forms the information is sent in the $_GET array. For some unknown reason I chose to use $_POST for the search data, but anyway...

For example, if someone chooses to display 1 record per page the page auto refreshes and shows that, and then if the user chooses to sort the results by ID, the page will forget that it's only displaying one record per page, and go to the default.

I've now gathered that it isn't possible (or atleast it doesn't work for me...) to pass $_GET data by specifying it in the action attribute of the form tag.

So now I'm thinking I'm either going to have to set the whole $_REQUEST array into a session or set the whole $_REQUEST array into hidden input fields in a HTML form and use JavaScript to auto submit this form aswell as any other forms that get submitted.

I'm using pagination at the bottom of the page, and decided upon text links for the pages, I loop through the $_GET array in that for the links, and manage to retain it through pages. So now I'm considering scrapping submit buttons altogether, and using text links for the forms at the top, and then just using JavaScript to pass the stuff in the fields along in the text link as $_GET data.

This must be a pretty common problem so I'm presuming theres a common way to do it which is probably alot better than any method I've mentioned :)

Thanks for any help.

On a side note: When using the get method with HTML forms, is there any way to stop the submit buttons value being passed along aswell? I know it sounds stupid because then you wont know if the form is set or not, but if I'm going to retain the $_GET data each time I will collectively have loads of forms submitting at once and my script will go haywire.
User avatar
Chris Corbyn
Breakbeat Nuttzer
Posts: 13098
Joined: Wed Mar 24, 2004 7:57 am
Location: Melbourne, Australia

Post by Chris Corbyn »

Code: Select all

<?php echo $_SERVER['QUERY_STRING'] ?>
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Post by Ambush Commander »

QUERY_STRING might be insecure, make sure you encode it properly. Also, it can cause problems if you have something like ?action=logout. I prefer explicitly stating which variables should carry over.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

I've always had no problem passing get through the action in the form, is this bad practice... can you post your code?
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Ambush Commander wrote:QUERY_STRING might be insecure, make sure you encode it properly. Also, it can cause problems if you have something like ?action=logout. I prefer explicitly stating which variables should carry over.
For the purposes of maybe an "are you sure?" page inbetween form filling and submission, $_SESSION['QUERY_STRING'] = $_SERVER['QUERY_STRING']; would be ok, surely?

Though I am in the same boat and would specify exactly which $_GET/$_POST var's are to be passed.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

For this type of problem you really have three option.

1. Stuff every value into every non-form link so that when you click on one of the related links all the form settings are passed on the URL like. This is the more straightforward but there is a lot of housework. Probably a central URL builder class would greatly simplify things.

2. Stuff the form settings into the Session and get the values from there if new values have not been POSTed. This is pretty easy too, but you need to deal with cases like if they return to the form do you want their old settings there.

3. AJAX. Update everything without a refresh so there is nothing to lose.
(#10850)
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Post by jayshields »

Thanks for the input guys, seems this will have to be messier than I thought after all.

There's no point posting all my code, I've got almost 500 lines and I use the $_GET array about once every 10 lines.

If you're talking about the action attribute in my form tag, I do it like this:

Code: Select all

//Set a variable which contains the self file name including all the GET data
$selfwithget = basename(__FILE__);
$tmp = FALSE;
$first = FALSE;
foreach($_GET as $key => $value) {
	if(strpos($key, 'submit') === FALSE) {	
		if($first == FALSE) $selfwithget .= '?';
		$selfwithget .= $key . '=' . $value . '&';
		$tmp = TRUE;
		$first = TRUE;
	}
} 
if($tmp == TRUE) $selfwithget = substr($selfwithget, 0, strlen($selfwithget) - 1);
...I posted this snippet a few days ago in another thread. I then use this:

Code: Select all

<form name="searchform" action="<?php echo $selfwithget; ?>" method="get">
If I view source it appears exactly how I would like it to, but it just doesn't work, I presume PHP automatically unsets the $_GET array before pushing new values into it from form submission.

I've just var_dump'd $_SERVER['QUERY_STRING'] and it's just a quick alternative to my snippet up there :oops: - but that still doesn't solve my problem.

How do you implement that solution into my problem d11?

Some of you mentioned explicity stating which values to pass across, that sounds good, but how would you implement that? I can undertand stating which values to pass and such, but how do I pass them? Can I see an example, or are you just referring to text-based links?

I'm starting to think that I should just scrap using HTML submit buttons and use text based links as submission/redirect links, I can then get JavaScript to pull the form data from the form elements and include it in the GET data on the links. Then I can loop through the existing GET data using the snippet above and add it to the stuff that needs to be included with the fresh user input.

If I would've known this would've been such a problem to begin with I would've used sessions for this, but changing now will mean changing alot of my app :(
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Just change your $_GET to $_REQUEST so you get post data as well, or better yet... change your form method to GET... No point in making JS simulate a method="get" form when you can just set method="get"... you will want something like

Code: Select all

<?
foreach($_GET as $key => $value) {
?><input type="hidden" name="<?=$key?>" value="<?=$value?>" /><?
}
?>
to dump the get array, you will obviously want an extra security layer then just putting raw get data into your output obviously but those are the basics
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Don't use short tags - soon to be deprecated (fingers crossed) and they pose cross-platform issues :)

And don't use $_REQUEST.. specify where your variables are coming from.. if they are post, use $_POST, if they are get, use $_GET.

Use POST for forms. GET is best used only for small tid-bits of info, such as page ID's, or functional ID's.

If you really must transfer $_GET between pages, you can store the REQUEST_URI in a session var, then parse the info after:

Code: Select all

<?php
session_start();

$_SESSION['REQUEST_URI'] = $_SERVER['REQUEST_URI'];

//separate page...

parse_str($_SESSION['REQUEST_URI'], $MYGETVARS);

echo $MYGETVARS['var'];

?>
Creating hideously long URI's is messy, and you have a shorter limit (255 chars) than if you used POST.
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Just out of curiosity where did you hear they were soon to be depreciated? As for the portability I have yet to find a single host that has them turned off, and php.ini has them enabled by default. Not advocating the usage but it is certainly fine, if not for just demonstrating the method in which to do something, if the OP wants to replace them with <?php echo $x; ?> that is his own prerogative.
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

Deprecated, not depreciated.

And I didn't say anyone said they were to be deprecated, I said fingers crossed .. going by the current processes of PHP's dev team to flush out the crap, I was hoping short tags would be in there with it.

Read here to see mentioned many times that short tags are discouraged:
http://www.php.net/basic-syntax
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Post by jayshields »

I just tried building a hidden form with all the existing $_GET data and then submitting it with the other forms but it didn't work :( I just built the hidden form at the top of the page and then added onSubmit="javascript: document.getdata.submit();" to all my other forms, I had the doubt that it wouldn't submit more than one form at once...

So now I'm gunna use sessions. I'll have to rewrite alot but it will work no doubt :)
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Post by josh »

Code: Select all

Using short tags should be avoided when developing applications or libraries that are meant for redistribution, or deployment on PHP servers which are not under your control, because short tags may not be supported on the target server. For portable, redistributable code, be sure not to use short tags.
I bet they will follow what they did with register globals and just have it in a php.ini file, off by default. Since our code would not ever be redistributed due to the contract, how would the use of short tags affect me?


Also sorry about that, guess spellcheck can't do everything for me...
User avatar
Jenk
DevNet Master
Posts: 3587
Joined: Mon Sep 19, 2005 6:24 am
Location: London

Post by Jenk »

PHP6 will see the removal of register_globals (well, it's been slated for removal) so hopefully other inconsistancies such as shortags will also be removed.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

jshpro2 wrote:I bet they will follow what they did with register globals and just have it in a php.ini file, off by default. Since our code would not ever be redistributed due to the contract, how would the use of short tags affect me?
It won't because that workaround will probably always be there. Both short tags and ASP tags have always been alternate syntax and not the standard <?php or <script syntax. But the recommendation has always been <?php.
(#10850)
Post Reply