mod_rewrite use variable's numeric position in url - apache

I apologize if the title isn't quite clear as I am new to mod_rewrite and I am not sure how to phrase the question correctly.
I want to rewrite a fancy url such as http://www.url.com/module/subdirectory/another_subdirectory/page to http://www.url.com/d_1=module&d_2=subdirectory&d_3=another_subdirectory&page=page. The number of subdirectories varies so the parameter d_* can be dynamic (trying to keep it between d_1 and d_9 though). The fancy url can also have its own query string and it needs to be rewritten to occur after the page parameter.
I did a read through of Apache's mod_rewrite and regex documentation and spent some time searching on Google and Stackoverflow for an answer to this but could not find anything for this specific problem. Any help on this problem from someone much more knowledgable would be greatly appreciated.

You can try something like below in the .htacess in the root directory, though you need to finish the cases up to 9.
I am also assuming that your CMS application is index.php. If not replace with correct .php file
RewriteEngine on
RewriteBase /
#one subdir
RewriteRule ^module/([^/]+)/([^/]+)$ index.php?d_1=module&d_2=$1&page=$2 [QSA,L,NC]
#two subdir
RewriteRule ^module/([^/]+)/([^/]+)/([^/]+)$ index.php?d_1=module&d_2=$1&d_3=$2&page=$3 [QSA,L,NC]
#three subdir
RewriteRule ^module/([^/]+)/([^/]+)/([^/]+)/([^/]+)$ index.php?d_1=module&d_2=$1&d_3=$2&d_4=$3&page=$4 [QSA,L,NC]

Alteration of Ulrich's code that doesn't need as much repeating, by making the subdir-parts optional. The last part always maps to page:
RewriteRule ^(module)/(?:([^/]+)/)?(?:([^/]+)/)?(?:([^/]+)/)?(?:([^/]+)/)?(?:([^/]+)/)?(?:([^/]+)/)?(?:([^/]+)/)?(?:([^/]+)/)?([^/]+)$ index.php?d_1=$1&d_2=$2&d_3=$3&d_4=$4&d_5=$5&d_6=$6&d_7=$7&d_8=$8&page=$9 [QSA,L,NC]
Though I would prefer to use some php code for this.
$dirs = expode('/', $_SERVER['REQUEST_URI']);
array_shift($dirs);//remove first empty string.
$page = array_pop($dirs);//get last part of the url.

Related

Using .htaccess mod_rewrite to pass all URLs in a given directory to a single redirect script

Im trying to use mod_rewrite to redirect any call to /real-estate/* to rewrite.php...i know i can redirect everything to rewrite.php with this:
RewriteRule ^(.*)$ rewrite.php?url=$1 [L]
I would like to have my urls formatted like /real-estate/12345/123-anywhere-st ....where the 123-anywhere-st would be ignored, and have /real-estate/12345 sent to rewrite.php...id like the rewrite rule to only be used on /real-estate...all other areas of the site should function as is...Ive searched all over for a good tutorial or cheat sheet, but none that I can find actually explain how to format the mod_rewrite rules, they just give one or two examples and thats it...can anyone help, as well as maybe provide a link to somewhere I can learn
Thanks!
RewriteRule ^/real-estate/(.*)$ rewrite.php?url=$1 [L]

mod_rewrite, only access one part of URL for blog entry

In other sites I've worked on, I have been able to easily generate search engine friendly URLS using the following in .htaccess:
<files entry>
ForceType application/x-httpd-php5
</files>
I'm working on a site hosted by a company that runs PHP as fast CGI and this does not work. I am trying to achieve the following URL - http://somewhere.com/blog/entry/12/this-is-the-title
I am just looking for the id (12 in the example) and do not necessarily need the title (my logic behind this being that the title might be changed by the client, links might be broken). I tried the following mod_rewrite but it does not work if I add the title:
RewriteEngine on
RewriteRule ^entry/([^/\.]+)/?$ index.php?id=$1 [L]
I've never worked with mod_rewrite before and a lot of the documentation I've come across is about achieving far more complex results. Any help would be appreciated
If the .htaccess file is in fact placed as /blog/.htaccess, you will need a RewriteBase /blog/ line.
Just looking for numbers will also help limit the returned id.
RewriteRule ^blog/entry/([01-9]+)/?$ index.php?id=$1 [L]
This also drops the '/?$' part of the regex. The '$' at the end anchors the match to the end of the string - you just need the numbers, and can ignore anything that is not a digit.

Apache Rewrite - put parts of query string in replacement string

I'd like to rewrite:
www.example.com/file.html?username=john&number=1234
To:
www.example.com/users/john
But I can't figure out how to extract the "username" value from the query string. I've been Googling this all morning and reading the official docs but no luck. I need to solve this problem with a rewrite, rather than changing the application.
Any help much appreciated!
Rangi
RewriteCond %{QUERY_STRING} username=([^&]+)
RewriteRule /?file.html /users/%1
Going to http://example.com/file.html?username=foobar will then redirect you to http://example.com/users/foobar, add an [R] to the end if you need an external redirect.
Mostly the rewrites are done the other way around, it's rare to see someone who wants a querystring in 'outside' urls but doesn't have them internally. Or did I understand your question backwards?
Ok I've solved this using two rules, although not sure if I'm doing it the best way.
RewriteRule ^file.html xxx/%{QUERY_STRING} [L]
RewriteRule ^xxx/[^=]*=([^&]*) /users$1 [R=301,L]
The first rule makes the query string part of the URL, so the second rule can see it, and therefore match and rewrite parts of it. I used "xxx" but it could be anything.

URL rewriting with mod_rewrite to provide RESTful URLs

The web server is Apache. I want to rewrite URL so a user won't know the actual directory. For example:
The original URL:
www.mydomainname.com/en/piecework/piecework.php?piecework_id=11
Expected URL:
piecework.mydomainname.com/en/11
I added the following statements in .htaccess:
RewriteCond %{HTTP_HOST} ^(?!www)([^.]+)\.mydomainname\.com$ [NC]
RewriteRule ^(w+)/(\d+)$ /$1/%1/%1.php?%1_id=$2 [L]
Of course I replaced mydomainname with my domain name.
.htaccess is placed in the site root, but when I access piecework.mydomainname.com/en/11, I got "Object not found".(Of course I replaced mydomainname with my domain name.)
I added the following statements in .htaccess:
RewriteRule ^/(.*)/en/piecework/(.*)piecework_id=([0-9]+)(.*) piecework.mydomainname.com/en/$3
Of course I replaced mydomainname with my domain name.
.htaccess is placed in the site root, but when I access piecework.mydomainname.com/en/11, I got "Object not found".(Of course I replaced mydomainname with my domain name.)
What's wrong?
Try using RewriteLog in your vhost or server-conf in order to check the rewriting process. Right now you just seem to guess what mod_rewrite does.
By using RewriteLogLevel you can modify the extend of the logging. For starters I'd recommend level 5.
PS: Don't forget to reload/restart the server after modifying the config.
Here's a quick overview of what's happening:
RewriteCond %{HTTP_HOST} ^(?!www)([^.]+)\.mydomainname\.com$ [NC]
First, the question mark is supposed to be at the end.
$1 would (should) match anything that is not 'www' 0 or 1 times.
$2 matches anything that is not a character 1 or more times, which theoretically would match a blank space there but likely would never match anything.
Then it requires '.mydomainname.com' after those two groupings.
Your first two conditions are looking for two separate groupings.
I'm not sure exactly how you're trying to set up your structure, but here is how I would write it based on your original and expected URL's:
RewriteCond %{HTTP_HOST} !^www\.mydomainname\.com$ [NC]
RewriteCond %{HTTP_HOST} ^(\w+)\.mydomainname\.com$ [NC]
RewriteRule ^(\w+)/(\d+)$ /$1/%1/%1.php?%1_id=$2 [L]
Basically, your first condition is to make sure it's not the URL beginning with 'www' (it's easier to just make it a separate rule). The second condition makes it check any word that could possibly be in front of your domain name. Then your rewrite rule will redirect it appropriately.
Get rid of the last .htaccess line there in your question...
Someone please correct me if I typed something wrong. I don't remember if you have to have the '\' in front of '\w' and '\d' but I included them anyways.
You are doing it backwards. The idea is that you will give people the friendly address, and the re-write rule will point requests to this friendly, non-existent page to the real page without them seeing it. So right now you have it only handling what to do when they go to the ugly URL, but you are putting in the friendly URL. since no rule exists for when people put the friendly URL directly, apache looks for it and says "Object not Found"
So add a line:
RewriteRule piecework.mydomainname.com/en/(*.) ^/$3/en/piecework/$3?piecework_id=([0-9]+)(.*)
Sorry, that's quite right, but the basic idea is, if they put in the URL you like, Apache is ready to redirect to the real page without the browser seeing it.
Update
I'm way to sleepy to do regex correctly, so I had just tried my best to move your example around, sorry. I would try something more simple first just to get the basic concept down first. Try this:
RewriteRule www.mydomainname.com/en/piecework/piecework\.php\?piecework_id\=11 piecework.mydomainname.com/en/11
At the very least, it will be easier to see what isn't working if you get errors.

mod_rewrite to alias one file suffix type to another

I hope I can explain this clearly enough, but if not let me know and I'll try to clarify.
I'm currently developing a site using ColdFusion and have a mod_rewrite rule in place to make it look like the site is using PHP. Any requests for index.php get processed by index.cfm (the rule maps *.php to *.cfm).
This works great - so far, so good. The problem is that I want to return a 404 status code if index.cfm (or any ColdFusion page) is requested directly.
If I try to block access to *.cfm files using mod_rewrite it also returns a 404 for requests to *.php.
I figure I might have to change my Apache config rather than use .htaccess
You can use the S flag to skip the 404 rule, like this:
RewriteEngine on
# Do not separate these two rules so long as the first has S=1
RewriteRule (.*)\.php$ $1.cfm [S=1]
RewriteRule \.cfm$ - [R=404]
If you are also using the Alias option then you should also add the PT flag. See the mod_rewrite documentation for details.
Post the rules you already have as a starting point so people don't have to recreate it to help you.
I would suggest testing [L] on the rule that maps .php to .cfm files as the first thing to try.
You have to use two distinct groups of rewrite rules, one for .php, the other for .chm and make them mutually exclusives with RewriteCond %{REQUEST_FILENAME}. And make use of the flag [L] as suggested by jj33.
You can keep your rules in .htaccess.