How Do You Properly Parse REDIRECT_QUERY_STRING?

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

Post Reply
User avatar
volomike
Forum Regular
Posts: 633
Joined: Wed Jan 16, 2008 9:04 am
Location: Myrtle Beach, South Carolina, USA

How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by volomike »

If you're using the ErrorDocument directive in your .htaccess file as a handy Front Controller technique, you'll find out your $_GET is empty when you pass parameters in. The fix is to pull $_SERVER['REDIRECT_QUERY_STRING'], but then you get a list sort of like this:

user%20name=volo%20name&test=1

So, I came up with the following routine. If you think I might have a problem with it, please let me know because I don't want to get some injection here from a $_GET and don't want to do this inefficiently.

Code: Select all

if ($_SERVER['REDIRECT_QUERY_STRING']) {
    $_GET = array();
    $_SERVER['QUERY_STRING'] = $_SERVER['REDIRECT_QUERY_STRING'];
    parse_str(preg_replace('/&(\w+)(&|$)/', '&$1=$2', strtr($_SERVER['QUERY_STRING'], ';', '&')), $_GET);
}
 
if (get_magic_quotes_gpc()) {
    function stripslashes_deep($sVal) {
        return is_array($sVal) ? array_map('stripslashes_deep', $sVal) : stripslashes($sVal);
    }
    if (($_SERVER['REDIRECT_REQUEST_METHOD'] == 'POST') or ($_SERVER['REQUEST_METHOD'] == 'POST')) {
       $_POST = array_map('stripslashes_deep', $_POST);
    }
    $_COOKIE = array_map('stripslashes_deep', $_COOKIE);
    if (($_SERVER['REDIRECT_REQUEST_METHOD'] == 'GET') or ($_SERVER['REQUEST_METHOD'] == 'GET')) {
       $_GET = array_map('stripslashes_deep', $_GET);
    }
}
So, this cleans up my $_GET, $_POST, and $_COOKIE, and makes it work even if I use the old ErrorDocument trick in my .htaccess. But I just want to make this even better if you can think of something else to throw in.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by alex.barylski »

I'm not sure I understand why you are having problems...

ErrorDocument directive...what does your .htaccess look like? Why can't you do something like:

Code: Select all

RewriteEngine on
RewriteRule ^(.+)$ index.php?page=$1 [QSA]
I'm not a .htaccess pro but I believe this will parse your URI's and set the appropriate GET variables so you don't have to manually split the URI into name=value pairs.

Cheers,
Alex
User avatar
volomike
Forum Regular
Posts: 633
Joined: Wed Jan 16, 2008 9:04 am
Location: Myrtle Beach, South Carolina, USA

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by volomike »

Alex,

This is what my .htaccess file looks like. I was reading up on stuff from Rasmus Lerdorf and he wasn't mentioning the rewrite technique for building a quick and dirty front controller. Instead, he mentioned the ErrorDocument method instead of the RewriteRule method. I don't know the pluses or minuses of it, so please enlighten me.

Code: Select all

IndexIgnore .htaccess   *~   *.conf   *.sql   *.xml
 
<FilesMatch "\.(sql|xml|conf|htaccess)">
    Deny from all
</FilesMatch>
 
<FilesMatch ".*~$">
    Deny from all
</FilesMatch>
 
# IF ON SERVER
<IfModule expires_module>
    ErrorDocument 404 /index.php
</IfModule>
 
# IF ON LOCAL DEVELOPER WORKSTATION
<IfModule !expires_module>
    ErrorDocument 404 /mysite.com/index.php
</IfModule>
 
LimitRequestBody 102400
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by alex.barylski »

This is what my .htaccess file looks like. I was reading up on stuff from Rasmus Lerdorf and he wasn't mentioning the rewrite technique for building a quick and dirty front controller. Instead, he mentioned the ErrorDocument method instead of the RewriteRule method. I don't know the pluses or minuses of it, so please enlighten me.
Most projects use Rewrite rules -- I have never seen ErrorDocument used for this before. I'm not sure I see any benefits although I would be concerned about not being able to show error documents if I wanted to -- assuming they were static HTML files.

Using a single index.php for entry lets me typically perform a check inside index.php for the existance of a page or module, etc and show a custom 404 page, so I have never needed to use ErrorDocument before.

I know that it would confuse me though, if I see that in .htaccess I wouldn't be sure of what was going on...

The greatest benefit of using rewrite rules is probably the automation of URI parsing and initialization of $_GET so you don't need to use custom split() type methods.
User avatar
volomike
Forum Regular
Posts: 633
Joined: Wed Jan 16, 2008 9:04 am
Location: Myrtle Beach, South Carolina, USA

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by volomike »

Yeah, you're right. I normally was using RewriteRule, but was doing it all the time for each set of requests, such as finding /e/ in the URL and translating it to /employers/ in the physical path. I then started trying out this ErrorDocument thing that I saw from Rasmus Lerdorf and a few other blogs.

But you're right. I just switched over to your RewriteRule technique, and sure enough I don't have to do all this parsing anymore. I am, however, sticking with the magic quotes adjustment unless someone knows of an htaccess trick to eliminate the need for the PHP code on that.
User avatar
volomike
Forum Regular
Posts: 633
Joined: Wed Jan 16, 2008 9:04 am
Location: Myrtle Beach, South Carolina, USA

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by volomike »

Ah, looks like I don't need the magic quotes check in PHP after all. Just do this at the bottom of the .htaccess file:

php_value magic_quotes_gpc 0
User avatar
volomike
Forum Regular
Posts: 633
Joined: Wed Jan 16, 2008 9:04 am
Location: Myrtle Beach, South Carolina, USA

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by volomike »

Okay -- first problem encountered. Now EVERYTHING is going through index.php. Okay, a little problem with that. That means that if I have an image file, I have to put an .htaccess exception for all the image types. And then if I have a legitimate file like test.php that I want users going to, I have to poke a hole with a rewrite rule in htaccess for that again. I think this is why people preferred the ErrorDocument route -- it was a slight pain on the GET code, but then a 3 liner would handle that, and then you don't have to put all these exceptions in your .htaccess file.
User avatar
Ambush Commander
DevNet Master
Posts: 3698
Joined: Mon Oct 25, 2004 9:29 pm
Location: New Jersey, US

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by Ambush Commander »

You can use the -f flag on RewriteCond to see if a page exists before redirecting to index.php. Makes it similar to ErrorDocument, but not quite ;-)
User avatar
volomike
Forum Regular
Posts: 633
Joined: Wed Jan 16, 2008 9:04 am
Location: Myrtle Beach, South Carolina, USA

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by volomike »

Okay, ErrorDocument was a great bit can of FAIL. Evidently Apache has a quirk where it won't send $_POST data on when you run through ErrorDocument. $_GET works with some modification, but not $_POST. If you do all your posts in AJAX, then you probably don't care. But if not, here's the resolution:

Code: Select all

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [QSA]  
 
RicardoF1RST3
Forum Newbie
Posts: 1
Joined: Mon Dec 03, 2012 5:28 am

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Post by RicardoF1RST3 »

Many thanks for this, it perfectly fits what I need.

Just to clarify for future readers, the cool thing about ErrorDocument /index.php in your HTACCESS is that it's a one line re-direct for all filenames which do not exist. So you can generate URLs and they all go to one file to be handled but any URL with file that exists reaches the required URL fine.

Drawback is that you dont get the $_GET & $_POST vars past.

The above solution replaces the ErrorDocument re-direct with a filter which passes control to any files which exist (-f) or directories (-d) but sends all other unknown requests to a single file, with [QSA] = query string append, so you also get the $_GET and $_POST vars - perfect! :D

- thats how I read anyway, correct me if i'm wrong.
Post Reply