mod_rewrite efficient optional parameter handling - php

I am building a site with a wide, wide variety of optional $_GET[] parameters: my url can range anything from
index.php?mod=reg to
index.php?mod=complicated&param1=foo or
index.php?mod=EvenMoreComplicated&w=4&x=1&y=2&z=3.
I understand that, in a way, this could be handled with a whole bunch of rewrite rules with an [L] parameter, however, isn't there an easier way to handle this without having to manually specify each possible $_GET[] parameter?

In many frameworks, this issue is tackled by one unique rewrite rule :
RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
That means that you get all the query string in one single parameter $_GET['url']
Then, parse_str() function in :
parse_str($_GET['url'], $queryArgs);
This will give you the $_GET equivalent in $queryArgs.
Also, this is demo code, don't forget sanitization/filtering in real code.
Hope this helps !

Related

PHP fake url, complex .htaccess rewrite_mod

I have real a lot about CakePHP, and php rewrite_mod, but i m so much confused about how to use it as i don't have knowledge about regex.
how can i have something like this?
mywebsite.com/en/ => mywebsite.com/?lang=en
mywebsite.com/en/about => mywebsite.com/about/?lang=en
mywebsite.com/en/search/?query=Hello+World => mywebsite.com/search/?query=Hello+World&lang=en
so in the reality my files are like:
public_html/about/index.php
public_html/search/index.php
public_html/index.php
but i m faking it like
public_html/en/about/index.php
public_html/en/search/index.php
public_html/en/index.php
and need to conserve the URL, and PARAMETERS passed through GET, i don't understand how to setup a so complex url controller in .htaccess
i've also tried following this but not getting out, is there any sample project?
cakephp 3 parameter url
Essentially, you rearrange the request URL. This means, you must capture (...) the parts separately, and put them together in the substitution $.... You also want to keep an existing query string, which requires the use of the QSA|qsappend flag. The RewriteCond is there to prevent a rewrite loop. If the rule was applied once, it shouldn't be used a second time.
RewriteCond %{QUERY_STRING} !lang=
RewriteRule ^(..)(.*)$ $2?lang=$1 [L,QSA]
To learn more about regular expressions, see Apache - Regular Expressions.

How do I change ugly URLs to pretty URLs using .htaccess? [duplicate]

I need to grab some of my website's old URLs and do a 301 redirect to the new ones, since they are already indexed and we don't want to loose relevance after the change. The old URL is in fact very ugly and for some reason everything I try to do to rewrite it does not work. Here it is:
http://www.mywebsite.com/ExibeCurso.asp?Comando=TreinamentoGeral&codCurso=136&Titulo=Como%20Estruturar%20um%20Sistema%20Gerencial%20de%20Controles%20Organizacionais,13
Basically, I need to translate it into something like:
http://www.mywebsite.com/curso/136
From the old URL I need to check if the user typed "ExibeCurso.asp"; then I know I must send him here: /curso. I must also grab the integer that was in the querystring parameter "codCurso" (136). What is the regular expression I must use for this. I am using ISAPI_Rewrite 3, which basically implements htaccess on IIS, so there should be no difference in terms of syntax. Thanks.
Try this rule:
RewriteCond %{QUERY_STRING} ^([^&]*&)*codCurso=([0-9]+)(&.*)?$
RewriteRule ^/ExibeCurso\.asp$ /curso/%2? [L,R=301]
But I’m not sure whether ISAPI Rewrite requires the pattern to begin with a slash.
Off the top of my head, something like this should work:
RewriteRule ^ExibeCurso.asp(.*)$ http://www.mywebsite.com/curso/$1 [L,R=301]
That would at least send the traffic to /curso/ with all parameters attached. Maybe it's best to process it from there.

CodeIgniter Mod Rewrite Rules and the Controller

Learning PHP, I am playing around with mod_rewrite and CodeIgniter. I have configured my .htaccess file correctly with
RewriteEngine On
RewriteRule ^(resources)/(.*) $1/$2 [L]
RewriteRule ^(user_guide)/(.*) $1/$2 [L]
RewriteRule (.*) index.php?$1 [L]
I understand a bit of regex, and can appreciate what happens here. The rewrite rules are applied and the server than handles the final URL which in the above case- attaches index.php (the front controller) to the "pretty" URL. So far so good.
I now want a URL pattern :
/<person-name>/at/<place>
to get translated to :
/index.php/person/list?personName=$1&place=$2
And i handle the request at my list function in the person controller. I do not understand why the following doesn't work:
RewriteRule ^([a-z]+)/(at)/([a-z]+)$ index.php/person/list?personName=$1&place=$2 [L]
What am i doing wrong/where is my understanding flawed? I see that the placeholders are extracted correctly ($1 and $3), however, it throws a CodeIgniter 404.
Many thanks!
It's possible that the simplest fix will fix your issue. By wrapping "at" in parentheses, you're creating another matching group, which means that $2 will always be "at." That could be breaking everything. You want index.php?person/list?personName=$1&place=$3 But you may have noticed that issue and fixed it without fixing the problem, in which case, read on.
Check out How to make CodeIgniter accept "query string" URLs?. It seems to indicate that you can't mix and match the segment-based approach and the query string approach. Without seeing your controller code, I can't say for certain, but I'd start investigating there. You might also try:
RewriteRule ^([a-z]+)/(at)/([a-z]+)$ index.php?person/list/$1/$3 [L]
which would do the same thing the general-purpose CI redirect rule below does; send the URL off to index.php as a query string for processing. You've said you got it working with routes, so rather than passing a query string to your controller, you can expect person and place as two arguments. CI's handling of query strings leaves a lot to be desired, and I've never tried to MOD_REWRITE something including a query string into a query string.

Rewrite .htaccess 2 GET variables not splitting?

Trying to write a rewrite rule to capture two GET variables
http://stackoverflow.com/blogs/category/general/1
RewriteRule ^blogs/category/(.+)/?$ blogs.php?category=$1 [PT,L,QSA]
RewriteRule ^blogs/category/(.+)/([0-9]+)/?$ blogs.php?category=$1&page=$2 [PT,L,QSA]
However when I grab these from the headers it looks like this?
$_GET['category'] = "general/1";
$_GET['page'] = "";
As you can see I have two rules, one for just when they provide category and one for when they also provide page number. Might be wrong about that approach I'm not sure.
What am I doing wrong here? How can I separate these variables properly using the rewrite rules (I know I could hack it in php but that's ugly)
I think you just have to switch them so that the more specific one is handled first:
RewriteRule ^blogs/category/(.+)/([0-9]+)/?$ blogs.php?category=$1&page=$2 [PT,L,QSA]
RewriteRule ^blogs/category/(.+)/?$ blogs.php?category=$1 [PT,L,QSA]
To explain that a little bit further: All regular expressions are greedy if not specified otherwise. Which means, that the regular expression tries to get as much as possible. (.+) matches "general/1".

Passing $_GET variables to virtual directories via .htaccess

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'].

Categories