Page 1 of 1

How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 4:38 pm
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.

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 5:41 pm
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

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 6:34 pm
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

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 6:46 pm
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.

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 6:55 pm
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.

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 6:59 pm
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

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 7:29 pm
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.

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Sun Dec 28, 2008 10:36 pm
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 ;-)

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Mon Dec 29, 2008 8:02 pm
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]  
 

Re: How Do You Properly Parse REDIRECT_QUERY_STRING?

Posted: Mon Dec 03, 2012 6:01 am
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.