Passing $_GET variables to virtual directories via .htaccess - php

I have the following .htaccess Rewrite rule below which works for converting virtual directories to parameters, for example:
www.example.com/usa/ny/nyc gets interpreted by PHP as www.example.com/index.php?path=usa/ny/nyc.
What I can't seem to figure out is how I would change my regex below to handle parameters of the virtual directories themselves. For example, I want:
www.example.com/usa/ny/nyc/?display=off&settings=none to be seen by PHP as www.example.com/index.php?path=usa/ny/nyc&param=display:off,settings:none.
What makes it extra tricky is that the parameters won't always be those two options I used in the example above, they will change dynamically. Any ideas or suggestions of how to go about accomplishing this?
RewriteRule ^/?([a-zA-Z_\-/]+)$ index.php?path=$1 [L]

Assuming you want to pass the query string unmodified, you can use the [QSA] (query string append) option like so:
RewriteRule /(.+)$ /index.php?path=$1 [L,QSA]
You can find the documentation for the QSA option here. From the docs:
With the [QSA] flag, a request for /pages/123?one=two will be mapped
to /page.php?page=123&one=two. Without the [QSA] flag, that same
request will be mapped to /page.php?page=123 - that is, the existing
query string will be discarded.
So, your PHP script will see all the parameters as standard _$_GET parameters, rather than needing to do any other modification.
If you would prefer to treat the result more like a typical path element, you can use the following:
RewriteRule /(.+)$ /index.php/$1 [L,QSA]
In the above case, your query string will still be appended, however you will need to handle the path explicitly using $_SERVER['PATH_INFO'].

Related

Passing variables to a well format URL

My .htaccess is something like this
RewriteRule ^search/([A-Za-z0-9-]+)$ search.php?keyword=$1 [L]
and it correctly displays results for example.org/search/tomato
but now i'd like to pass variables to it, but when i do it like
example.org/search/tomato?color=green
it doesn't work.
what's the common practice to solve this problem?
Use:
RewriteRule ^search/([A-Za-z0-9-]+)$ search.php?keyword=$1 [QSA,L]
QSA|qsappend When the replacement URI contains a query string, the
default behavior of RewriteRule is to discard the existing query
string, and replace it with the newly generated one. Using the [QSA]
flag causes the query strings to be combined.

Phalcon PHP can't get $_GET variable

I'm a beginner with Phalcon and I just can't figure out what's happening. I'm working with OAuth2.0 and I'd like to get the authorization code from the query parameter.
As stated in the documentation, I have to use $request->getQuery().The thing is, it gives me something completely different.
The URI is like this:
https://my.site/controller/method?foo=bar
Using var_dump($request->getQuery()); returns the following:
array(1) { ["_url"]=> string(12) "/controller/method" }
This seems like the URL part in the Apache .htaccess RewriteRule that is shown in the Phalcon examples. (RewriteRule ^(.*)$ /index.php?_url=/$1 [P,L] (I changed the flags only))
What am I doing wrong?
You can add the [QSA] flag to the RewriteRule to retain query strings.
From the docs:
When the replacement URI contains a query string, the default behavior
of RewriteRule is to discard the existing query string, and replace it
with the newly generated one. Using the [QSA] flag causes the query
strings to be combined.
Something like this:
RewriteRule ^(.*)$ /index.php?_url=/$1 [P,L,QSA]

.htaccess $_GET specification

I have .htaccess code to maintain my URLs:
RewriteRule ^2014/?(?:([^/]+)/?|)(?:([^/]+)/?|)$ /data/2014/index.php?section=$1&subsection=$2 [L]
I need to modify it for cases, when i run form with get method. It makes output as (for ex.)
myweb.com/2014/about/?person=1&page=2
which I want URL to understand, I mean to get in the end hidden
myweb.com/data/2014/index.php?section=about&person=1&page=2
Thank you for any help.
You need the QSA flag:
RewriteRule ^2014/...$ /data/...&subsection=$2 [L,QSA]
^^^ here
That will append / combine the original query string to the rewritten url.

Can't get $_GET after Apache rewrite [duplicate]

I'm trying to rewrite an url from:
http://domain.com/aa/whatever/whatever.php
to
http://domain.com/whatever/whatever.php?language=aa
However, depending on existing $_GET variables, it either has to be ?language or &language.
To do this, I use 2 regexes with the [L] flag:
RewriteRule ^([a-z]{2})/(.*\.php\?.*) /$2&language=$1 [L]
RewriteRule ^([a-z]{2})/(.*) /$2?language=$1 [L]
The second one works as expected... The first one however is never hit (it falls through to the second regex, which does hit), even though Regex Coach does show me that it should.
edit:
If just read that I need to use two backslashes to escape the question mark. If I do this, it does hit on the first regex but never find the other GET variables.
From the documentation for mod_rewrite the pattern in RewriteRule matches against the part of the URL after the hostname and port, and before the query string so the query string is not included. That is why you don't get the other variables.
To add a new query string parameter language=xx whilst preserving any existing query string you need to use the QSA flag (query string append). With this flag, just one rule based on your second case should be sufficient:
RewriteRule ^([a-z]{2})/(.*) /$2?language=$1 [QSA]
You could setup the URL rewrite to pass the language to the php script via the PATH_INFO element of the $_SERVER superglobal. Just pass the language to the script like so:
foobar.php/en?args
In this case, $_SERVER[PATH_INFO] would equal /en

How to use mod_rewrite with Zend Framework?

I've just deployed a new site using Zend Framework. Due to the popularity of my tutorials I'd like to redirect any request for a tutorial to the relevant page on the new site. So far this is what I've got:
URL before Rewrite: http://neranjara.org/tutorials/?tid=56
URL after Rewrite: http://neranjara.org/article/id/56
The .htaccess file I'm attempting to use looks like this:
$ cat html/.htaccess
RewriteEngine on
RewriteRule tutorials/\?tid=(.*)$ /article/id/$1 [R=301]
RewriteRule !\.(js|ico|gif|jpg|png|css|xml|phps)$ index.php
But this rule is not matching any URLs ... :'(
Does any one see a problem here?
Based on your previous entry:
$ cat html/.htaccess
RewriteEngine on
RewriteRule tutorials/\?tid=(.*)$ /article/id/$1 [R=301]
RewriteRule !\.(js|ico|gif|jpg|png|css|xml|phps)$ index.php
I'd suggest using this instead:
$ cat html/.htaccess
RewriteEngine on
RewriteCond %{QUERY_STRING} ^tid=([^&]*)
RewriteRule tutorials/ /article/id/%1 [R=301, L]
RewriteRule !\.(js|ico|gif|jpg|png|css|xml|phps)$ index.php [L]
BTW, this is just an example of the many things you could do using the QUERY_STRING variable in mod_rewrite. My vote goes to 'lpfavreau' since this is option #2 from their answer.
The query string (the parameters passed to your file) won't be in the RewriteRule.
Taken from http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html#rewriterule:
The Pattern will not be matched
against the query string. Instead, you
must use a RewriteCond with the
%{QUERY_STRING} variable. You can,
however, create URLs in the
substitution string, containing a
query string part. Simply use a
question mark inside the substitution
string, to indicate that the following
text should be re-injected into the
query string. When you want to erase
an existing query string, end the
substitution string with just a
question mark. To combine a new query
string with an old one, use the [QSA]
flag.
You have two possibilities here:
Remove your first RewriteRule and do the verification in your index.php instead before continuing to your framework. The initial query should be available in $_SERVER['REQUEST_URI'] or something like that. So verify if it's tutorials, take the tid parameter and then go on with a redirection:
header("Location: http://http://neranjara.org/article/id/$id");
exit();
Use RewriteCond with %{QUERY_STRING} instead as stated in the Apache documentation. This solution is discussed in thread like this one.
// Edit:
Have a look at Chris' answer who was kind enough to detail the solution using QUERY_STRING. This is probably what you'll want to use. Thanks Chris.
Zend uses all the htaccess power that htaccess can deliver so theres a very handy(chainable and interesting and not very well documented) method to achive this in the bootstrap!
You must use the Zend Router in your bootstrap (index.php). Probably something like: (this would be foo.com/article/23
$router =
$frontController->getRouter();
$route = new
Zend_Controller_Router_Route(
'article/:id',
array('id' => 1) ); $router->addRoute('article', $route);
More info here

Categories