I hope someone can help me with a mod_rewrite rule, that works apart from adding trailing slashes.
This is the rule
<IfModule rewrite_module>
Options Indexes FollowSymLinks +IncludesNOEXEC
RewriteEngine On
RewriteCond %{HTTP_HOST} !^www\.mydomain\.org$ [NC]
RewriteRule ^(.*)$ http://www.mydomain.org/$1 [L,R=301]
</IfModule>
The purpose is to rewrite the URL mydomain.org in the form www.mydomain.org
This works. but then www.mydomain.org// shows in the browser address bar. Checking the rewrite log shows that the // is explicitly created by the rule
Questions are:
Do (or could) the two slashes matter?
If the answer to (1) is yes, can I redo the rule so that the trailing slashes are omitted?
Most servers ignore the double slash and treat it as a single. See for example this question (double-slash) https://stackoverflow.com//questions/13027041
To fix your RewriteRule, I believe you just need to change it to
RewriteRule ^/?(.*)$ http://www.mydomain.org/$1 [L,R=301]
The /? part makes it optional (root access), and if it is found, it gets stripped since it is not part of the captured (.*) section.
No, two slashes generally doesn't matter, it doesn't confuse software anyhow. It just means you have to transfer one byte more (which can matter in some situations).
Just change your rewrite rule to RewriteRule ^/?(.*)$ http://www.mydomain.org/$1 [L,R=301]. That /? is what does the trick.
Related
I have a URL that appears like this
http://www.domain.com/previous-winners/?ceremony=406&title=2015
and i'm trying to rewrite this with my .htaccess file to appear like this. Keeping the title parameter and dropping the ceremony one.
http://www.domain.com/previous-winners/2015
This is what i have so far
RewriteRule ^previous-winners/$2 /previous-winners/?ceremony=$1&title=$2 [NC]
But i'm not really sure where to go next.
Use this rule in your .htaccess:
RewriteEngine On
RewriteRule ^previous-winners/([^/]*)$ /previous-winners/?ceremony=406&title=$1 [L]
It will leave you with the URL: http://www.domain.com/previous-winners/2015
Just make sure you clear your cache before you test this.
i need help regarding nice looking referral link. for example here is a referral link
http://www.my-domain.com/register.php?ref=john.doe
this is a perfect url but not looks good like the following
http://www.my-domain.com/john.doe
how can i achieve this using .htaccess file? please note that, i have index.php, member.php and other many php files in my server. moreover, if someone write my-domain.com it need to hit index.php file.
any help is highly appreciated.
Based on your example you can use the following .htaccess:
DirectoryIndex index.php
RewriteEngine On
RewriteRule ^([a-zA-Z]+\.php)$ $1 [NC,L]
RewriteRule ^([a-zA-Z]+\.[a-zA-Z]+)$ register.php?ref=$1
This works as following:
Line 1: Sets your index file to index.php if someone accesses http://www.my-domain.com/. This should already be working, but just in case.
Line 2: Enables the RewriteEngine.
Line 3: If someone wants to access anything (technically: anything with at least one character) ending with .php, it is just forwarded (i.e. foo.php will be mapped to foo.php). [NC,L] enables case insensitive matching (for the extension - you never know) and prevents any further rules from being executed. Otherwise the second one would also match every time.
Line 4: If someone wants to access anything matching "at least one character, a dot, at least one more character", then this will be mapped to register.php?ref=<input>
Note: This will effectively prevent all user names ending with .php, but allow access to all your files. It will also prevent user names containing less or more than one dot and it will in its current form not work if your files or user names contain any other characters (e.g. foo_bar.php or i_love_php). But those two limitations can be easily overcome if needed, just provide more details regarding expected behaviour.
You could add a RewriteCond to check if there actually exists a .php file with the requested name and treat it as user name otherwise, but I really don't think you should do that (think about adding new files).
This will get you what you need. This rule will handle nice link and also redirect old link to nice link.
DirectoryIndex index.php
RewriteEngine On
RewriteCond %{THE_REQUEST} ^GET\ /+register\.php\?ref=(.+)
RewriteRule ^ %1? [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ /register.php?ref=$1 [L]
I have a cascade problem with my .htaccess rules. Consider the following:
RewriteEngine on
RewriteRule ^product/(.*)$ product.php [L,QSA]
RewriteRule ^(.*)$ index.php [L]
With the above, if I requested a URL like http://example.com/product/product-slug, then I’d expect the request to get routed to product.php. However, it doesn’t; my index.php script is picked the request up.
I would have thought that the first RewriteRule would be matched, and as it has a L (last) flag that no further RewriteRules would be matched, including the “catch-all” one at the bottom.
Why is this not working as expected?
This should sort it:
RewriteRule ^product/(.*)$ product.php [L,QSA]
RewriteCond %{REQUEST_FILENAME} !product.php
RewriteRule ^.*$ index.php [L]
The problem is that because the rules were in different sets, i.e. not attached a condition, it only stopped processing the current set of rules (the first one) and jumped onto the second.
Hope that clears it all up :)
Perhaps a typo in your code? You're writing "http://example.com/products/" in your question, but in the code you're targeting ^product$, with no s.
Also, your first rule is too strict. It will only match http://example.com/product/. You need to include a wild card after product to allow it to pick up product-slug. Something like RewriteRule ^products/(.*)$ product.php [L,QSA] should work.
Is it not because of the order you have placed the rules in? The one below will override changes to the one above it. Try changing them around.
Also, do you need to set the RewriteBase or not? Is your project on an actual domain, or locally stored in a sub-directory of the server root?
I've been working on a solution to this for several hours now & figured if someone doesn't mind helping me out, it might save me some time. My question is with regards to Apache mod_rewrite; of course there is tons of documentation out there, however nothing specific to my requirements which are:
to take a URL in this format:
language/pagename.php
(language will either be 'english' or 'french', I will write a separate rule for each. [only need an example for one though]. page name will be any word character (w+). all URLs will have a .php extension).
And then rewrite it so the URL doesn't change in the users browser, but so that php could receive it in this format:
language/page.php?slug=pagename
e.g. so $_GET['slug'] would return the value pagename, and all requests are then handled by page.php.
So far my best guess is
RewriteEngine On
RewriteBase /
RewriteRule ^english/(\w+).php$ english/page.php?slug=$1
However this make php tell me that slug=page for this URL for example english/financial.php; rather than financial.
Have tried a bunch of other regex conventions too (.) instead of w & so on..
Use these rules:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(english|french)/([^/\.]+)\.php$ /$1/page.php?slug=$2 [NC,QSA,L]
This needs to be place in .htaccess file in root folder. If you will be placing it config file (e.g. httpd-vhost.conf, inside <VirtualHost> directive), then rule needs to be slightly altered.
This rule should work for any language, as long as you add it into the rule (english|french part).
This rule has a condition which will not rewrite if such file already exists. This should solve your problem with slug=page: in your rule you most likely have a rewrite loop (after rewrite occurs it goes to the next iteration -- that's how mod_rewrite works, and you need to have some logic in place to break this loop). Instead of RewriteCond %{REQUEST_FILENAME} !-f you could use RewriteCond %{REQUEST_URI} !^/(english|french)/page\.php [NC] but it is a bit more difficult to maintain (you need to add languages here as well as in rewrite rule itself).
If you already have some other rewrite rules then take care with placing these in correct place (order of rules matters).
Because I do not know for sure what page names (slugs) would be, I've used this pattern: [^/\.]+ (any characters except / or .) .. but you may change it to \w+ or whatever you think will be better.
Rule preserve any optional page parameters (query string) -- useful for preserving referrals/tracking code etc.
I have a problem with RewriteRule flags. I have a "main" RewriteRule that handles my application, but I also have some urls that need to be handled differently (see them as custom routes).
I've tried many different flags, but it never gives me the result I want. Check the first comment in the code for what I want.
# First check if this pattern is found, and if it's not, continue to the next one and disregard this one
RewriteRule ^test/report/([0-9]+)/?$ index.php?page=report&id=$1 [PT,L]
RewriteRule ^(.*)/?$ index.php?page=$1 [PT,L]
Thanks in advance!
You use the C flag, for chaining, on your first rule, which means that the second rule will be disregarded if the first does not match. Your comment describes what would happen without the C flag. I think you may want an L flag instead if you want to avoid applying the second rule if the first rule matches.
Edit:
Now that you've changed the C flag to L on your first rule, there is another issue. You need to ensure that a rewritten path does not get re-processed by your RewriteRule directives in some way that will change it.
In this case, one way to accomplish that goal is to ensure that the page itself is not already rewritten to index.php:
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^test/report/([0-9]+)/?$ index.php?page=report&id=$1 [PT,L]
RewriteCond %{REQUEST_URI} !index.php
RewriteRule ^(.*)/?$ index.php?page=$1 [PT,L]
Unfortunately, I do not know of a way to make the same RewriteCond apply to all your rules other than repeating it before each one.
Edit:
Now that I think of it, yes, there is possibly a somewhat better solution. Instead of using the RewriteCond directives, start with:
RewriteRule ^index.php - [PT,NC,L]
Now, anything starting with index.php will match, nothing changes, and no more RewriteRules will be followed.