Though .htaccess, I want to redirect /page/var1/var2 to ./page.php?var1=var1&var2=var2. This is very easy BUT I want to make it so /page/var1 also redirects to ./page.php?var1=var1 (without having the var2). The only way I'm doing this is:
RewriteRule page/(.*)$ ./page.php?var1=$1
RewriteRule page/(.*)/(.*)$ ./page.php?var1=$1&var2=$2
As you can see it's very redundant, and I have a ton of lines like this, so it gets very messy. Any way to define "optional" parts?
The expression .* matches both var1 and var1/var2 thus the first rule is applied on both.
So you have to specify it that the first rule only matches var1. This can be done by replacing . (any character) by [^/] (any character except /). So try this:
RewriteRule ^page/([^/]+)$ ./page.php?var1=$1
RewriteRule ^page/([^/]+)/([^/]+)$ ./page.php?var1=$1&var2=$2
Edit You can also write this in one rule:
RewriteRule ^page/([^/]+)(/([^/]+))?$ ./page.php?var1=$1&var2=$3
mod_rewrite is not well suited to such heavy lifting, leave that to your PHP app.
RewriteRule page/(.*)$ ./page.php?vars=$1
and somewhere near the beginning of page.php:
<?php
$vars = explode('/',$_GET['vars']);
Voila, you have an array of your vars; now you could do some processing there to see what is required/optional for your app and react accordingly.
The best approach is to just hand everything over to your PHP script.
I wrote an article on how to do friendly URLs, which covers this in more detail.
Related
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.
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.
I just know how htaccess works but I am always confused with the writing syntax and I appreciate if anyone could help me solving the below htaccess issue.
I have couple pages linking to redirect to something like
http://mydomain.com.au/product-details.php/142/categoryAbstract
but due to the mistakes of previous developer the images are not loading unless that url is
http://mydomain.com.au/product-details.html/142/categoryAbstract
He converted all php pages to html (I really don't know what's this intention in doing that) but
now the url should work even if it as http://mydomain.com.au/product-details.php/142/categoryAbstract
He used the below htaccess for this but its not working. If I manually change the url from .php to .html everything working fine.
RewriteRule ^product-details.html/(.*)/(.*)$ product-details.php?productid=$1&category=$2
I need a working line of code so that even the url http://mydomain.com.au/product-details.php/142/categoryAbstract should work.
You will just need an OR group (a|b) to account for both possibilities:
RewriteRule ^product-details\.(html|php)/(.*)/(.*)$ product-details.php?productid=$1&category=$2
#---------------------------^^^^^^^^^^^
That can be improved a little though. The (.*) are greedy matches. You are better served to use ([^/]+) as the first grouping to match everything up to the next /. I have also escaped the dot as \. so it is matched as a literal instead of any character.
RewriteRule ^product-details\.(html|php)/([^/]+)/(.*)$ product-details.php?productid=$1&category=$2
The .php extension is commonly modified either through rewriting or actual file renaming and server configuration to parse .html as .php in order to hide some server-side information from end users. To prevent them from knowing what technologies the site runs on the back end. It less common to actually rename files to .html than to use URL rewriting to hide the .php, however.
RewriteRule ^product-details.html/(.*)/(.*)$ product-details.php?productid=$1&category=$2
What this rule does is take everything after product-details.html/ and before the last / and a second bit gets taken after the last / until the end of the line. then it takes those bits and puts them where the $1 and $2 are.
to change it so it accepts .html and .php you can change it with
RewriteRule ^product-details(.html|.php)/(.*)/(.*)$ product-details.php?productid=$2&category=$3
Because it looks like the first bit you are grabbing are numbers and (.*) is a greedy selector it may be better to replace it with ([0-9]*) which will only select numbers. that way if you ever have /s in your catagory you'll be fine. giving you:
RewriteRule ^product-details(.html|.php)/([0-9]*)/(.*)$ product-details.php?productid=$2&category=$3
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".
Is it possible to use .htaccess to process all six digit URLs by sending them to a script, but handle every other invalid URL as an error 404?
For example:
http://mywebsite.com/132483
would be sent to:
http://mywebsite.com/scriptname.php?no=132483
but
http://mywebsite.com/132483a or
http://mywebsite.com/asdf
would be handled as a 404 error.
I presently have this working via a custom PHP 404 script but it's kind of kludgy. Seems to me that .htaccess might be a more elegant solution, but I haven't been able to figure out if it's even possible.
In your htaccess file, put the following
RewriteEngine On
RewriteRule ^([0-9]{6})$ /scriptname.php?no=$1 [L]
The first line turns the mod_rewrite engine on. The () brackets put the contents into $1 - successive () would populate $2, $3... and so on. The [0-9]{6} says look for a string precisely 6 characters long containing only characters 0-9.
The [L] at the end makes this the last rule - if it applies, rule processing will stop.
Oh, the ^ and $ mark the start and end of the incoming uri.
Hope that helps!
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteRule ^([0-9]{6})$ scriptname.php?no=$1 [L]
</IfModule>
To preserve the clean URL
http://mywebsite.com/132483
while serving scriptname.php use only [L].
Using [R=301] will redirect you to your scriptname.php?no=xxx
You may find this useful http://www.addedbytes.com/download/mod_rewrite-cheat-sheet-v2/pdf/
Yes it's possible with mod_rewrite. There are tons of good mod_rewrite tutorials online a quick Google search should turn up your answer in no time.
Basically what you're going to want to do is ensure that the regular expression you use is just looking for digits and no other characters and to ensure the length is 6. Then you'll redirect to scriptname.?no= with the number you captured.
Hope this helps!