htaccess rewriting to wrong page - web-services

I have begun learning htaccess and i'm massively struggling. I'm simply trying to remove my .php from a URL
subdomain.example.com/weddings.php
to
subdomain.example.com/weddings/
to be honest that's not entirely it. the full url is
subdomain.example.com/weddings.php?section=pyromusicals#divname
which im trying to make into
subdomain.example.com/weddings/divname
for now though just the removal of the .php to / would be helpful.
so far I have in my htaccess file
RewriteEngine on
RewriteCond %{REQUEST_URI} ^/(.*).php$
RewriteRule ^(.*)$ %1 [L,QSA]
which is re-writing to
subdomain.example.co.uk/wedding-fireworks/
which is great but it also generates a 404 error page not found.
The requested URL /wedding-fireworks/index was not found on this server.

Is this what you are wanting to do?
RewriteRule ^([^/]+)/([^/]+) /$1.php?section=pyromusicals#$2 [QSA,L]
RewriteRule ^([^/]+) /$1.php [QSA,L]
Note that is assuming your section will always = pyromusicals
If section changes, you will need to include it in your URL also example below.
http://www.yoursite.com/somephppage/nameofsection/divname
Then your mod rewrite would look like this.
RewriteRule ^([^/]+)/([^/]+)/([^/]+) /$1.php?section=$2#$3 [QSA,L]
RewriteRule ^([^/]+) /$1.php [QSA,L]

Related

Rewrite URL's .htaccess

I believe it might be a possible duplicate. But I tried my best to search for such a thing that will suit my needs and I found, none.
So here's basically what I have so far, and I will explain what I need modified.
# Forbidden Access
ErrorDocument 403 /403.php
# Not Found
ErrorDocument 404 /404.php
<IfModule mod_rewrite.c>
Options +FollowSymlinks
RewriteEngine On
RewriteBase /
</IfModule>
<IfModule mod_rewrite.c>
# Strip off .php extension if it exists
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R,L,NC]
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ /403.php$1 [R=301,L]
# Resolve .php file for extensionless php urls
RewriteRule ^([^/.]+)$ $1.php [L]
</IfModule>
Now this seems to be working flawlessly. But it has one error. Let me explain first.
1) It does automatically strip-off .php extension if it exists. Not sure if it strip off .php if it is url of an external request. Forgot to check, but maybe you already know so you can tell me ?
2) When I type this... "http://website.dev/img/" it does give me an "403 Forbidden Access". So that's all good.
3) When I try this... "http://website.dev/index" it does load the page even if there is .php extension manually added it will strip it off. So All good in here too...
4) When I try random path like this... "http://website.dev/asdasd" it does give me an "404 Not Found". So we're good in here as well.
But the main problem is here...
5) When I try following... "http://website.dev/dashboard/index" it give me an 404 Not Found even tho it should be loading without issues. It appears for all pages within dashboard directory.
Can you help me to modify that htaccess above please ? I am really tired of searching and I don't know regex at all.
That is because of the faulty regex used in your very last rule to silently add .php extension. Change last rule to:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_URI}\.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]
Here's my translation of you rules:
# Strip off .php extension if it exists
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
Bad comment. You regexp means: strip off all files that have 3 uppercase first and and dot php in it. Maybe you've forgotten the ending $?
# Unless directory, remove trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/$ /403.php$1 [R=301,L]
Why is that? Just do a redirect, and Apache will handle the 301 it for you:
RewriteRule .* - [L,R=403]
And then last question: why you strip off .php extension, if you re-add it later on? (°_o)
So here's what you should do, with some examples, and adapt them you fit your needs:
First test if the file has no special treatment. If so, stop immediately, like this:
RewriteRule ^/(robots\.txt|404\.php|403\.php)$ -
Then test if someone is trying to hack. If so, redirect to whatever you want:
RewriteRule (.*)test.php - [QSA,L]
RewriteRule (.*)setup.php http://noobs.land.com/ [NC,R,L]
RewriteRule (.*)admin(.*) http://noobs.land.com/ [NC,R,L]
RewriteRule (.*)trackback(.*) http://noobs.land.com/ [NC,R,L]
Then, only after this, forbid the php extension:
RewriteRule (.*)php$ - [L,R=404]
Then, accept all static "known" file extension, and stop if it matches:
RewriteRule (.*)(\.(css|js|htc|pdf|jpg|jpeg|gif|png|ico|mpg|mp3|ogg|wav|otf|eot|svg|ttf|woff)){1}$ $1$2 [QSA,L]
Now you can do some testing. If the URI ends with a 'aabb/', test if you have a file named aabb.php, and if so, go for it:
RewriteCond %{REQUEST_URI} (\/([^\/]+))\/$
RewriteCond %{DOCUMENT_ROOT}/%1.php -f
RewriteRule (.*) %{DOCUMENT_ROOT}/%1.php [QSA,L]
If nothing is handled, and you get here, it's a problem, so stop it:
RewriteRule .* - [L,R=404]
FYI, all those sample rules are deeply tested on a production server.
And now with that, you have all what you need to do something good & working.

htaccess rewrite rule not redirecting

I have recently re-coded a website and I have the following line which works great for making a friendly looking URL.
RewriteRule ^mydir/([^/]+)/?$ /page.php?menu=mydir&vid=$1 [L,QSA]
However, I have found out that there are some old links out there which have an altogether different look to them which I also need to rewrite.
So I tried this...
RewriteRule ^mydir/detail/\?id=([^/]+)?$ /page.php?menu=mydir&vid=$1 [L,QSA]
RewriteRule ^mydir/([^/]+)/?$ /page.php?menu=mydir&vid=$1 [L,QSA]
The url containing /detail/ does not rewrite though. Any ideas why?
You cannot match query string using RewriteRule. Change your rules to this:
RewriteCond %{QUERY_STRING} ^id=([^&]+) [NC]
RewriteRule ^mydir/detail/?$ /page.php?menu=mydir&vid=%1 [L,QSA]
RewriteRule ^mydir/([^/]+)/?$ /page.php?menu=mydir&vid=$1 [L,QSA]

.htaccess Pretty URL not displaying correctly with redirection

I am trying to configure a dynamic mod rewrite rule in my .htaccess file using mod_rewrite. I am very close to figuring this out. I am trying to get URLs like these:
http://www.mysite.com/index.php?service=14&title=events
http://www.mysite.com/index.php?service=48&title=planning
To automatically be rewritten to these:
http://www.mysite.com/service/14/events
http://www.mysite.com/service/48/planning
Here is my codes so far:
RewriteRule ^service/(.*)/(.*)$ index.php?service=$1&title=$2 [NC,L]
RewriteCond %{QUERY_STRING} ^service=$1&title=$2 [NC]
RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /index.php [NC]
RewriteRule ^index.php$ /service/$1/$2 [L,R=301]
I think there is something wrong with the last line maybe? I'm not the best at regular expressions so any help would be greatly appreciated.
Edit: Just wanted to be clear that the pretty URLs do work. However, the old URLs aren't redirecting and are still displaying in the browser.
I am not sure if this would be any easier but if I could get the URLs to look like this:
http://www.mysite.com/service/14/title/events
http://www.mysite.com/service/48/title/planning
Then that would work too. I don't really need the second query title to be in the URL but if it's easier to leave it in there, then no big deal.
Edit: Answered
Many thanks to all who helped contribute to the solution. I got this for my rewrite rule:
RewriteRule ^index/service/(.*)/(.*)/$ index.php?service=$1&title=$2
Once I added 'index' it worked with both query strings. As far as the redirect goes, I edited my php script and did all the URL redirecting there, which was a lot easier. Special thanks to mkjasinski for pointing that out.
Try this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^service/([0-9]+?)?/([a-zA-Z\-]+?)$ index.php?service=$1&title=$2 [L,NC]
and if I have run: http://localhost/service/12/This-is-text in $_GET in index.php:
array (size=2)
'service' => string '12' (length=2)
'title' => string 'This-is-text' (length=12)
you can't use special holders ($1,$2...) from previous rewrite rules into rewritecond.
change your code to:
RewriteRule ^service/(.*)/(.*)$ index.php?service=$1&title=$2 [NC,L]
RewriteCond %{QUERY_STRING} (?:^|&)service=([0-9]+)(&|$) [NC]
RewriteCond %{QUERY_STRING} (?:^|&)title=([a-z]+)(&|$) [NC]
RewriteRule ^index.php$ /service/%1/%3? [L,R=301]

mod-rewrite recursive loop

I want to change my website's dynamic urls to Search Engine Friendly URL's
Now the urls like this www.website.com/news.php?id=127591 ,
I want it became this www.website.com/news/127591/this-is-article-subject
I added this
RewriteRule ^news/([0-9]+) /news.php?id=$1 [PT]
in my .htaccess file. Everything from /news.php?id=123 change to /new/123/this-is-article-subject
The problem is, now I have two links refer to the same contents. Both /news.php?id=123 and /new/123/this-is-article-subject are the exactly duplicate content
It is said that search engine will punish this if they found duplicated contents.
I check the answers online and found this,
RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^news\.php /news/%1? [R=301,L]
HTTP 301 permanent redirect from the old URL to the new URL.
But this still have problem. When I put those three lines together, it not works.
RewriteRule ^news/([0-9]+) /news.php?id=$1 [PT]
RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^news\.php /news/%1? [R=301,L]
I guess the reason is the recursive loop. How could I solve this kind of problem?
Thanks!
Update
I changed to this
RewriteRule ^news/([0-9]+) /news.php?id=$1 [L]
RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^news\.php /news/%1? [R=301,L]
None of the two url work.
Please try this rule in your .htaccess file:
RewriteEngine on
Options +FollowSymlinks -MultiViews
RewriteCond %{THE_REQUEST} \?id=([0-9]+)\s [NC]
RewriteRule ^news\.php /news/%1? [R=301,L]
RewriteRule ^news/([0-9]+) /news.php?id=$1 [L,NS,NE,QSA,NC]
UPDATE:: Based on your comments:
Inside news.php when URL doesn't have /some-title then output this META tag to stop indexing /news/987 type URIs:
<meta name="robots" content="NOINDEX, NOFOLLOW">
Once you notice URI of /news/987/some-title inside news.php simply mask above META tag.
I have tested it and seems to be working fine so let me know if doesn't work for you.
You need to inspect the URI in the HTTP request line (i.e. %{THE_REQUEST}) as the other could already have been rewritten (like in your case):
RewriteCond %{THE_REQUEST} ^GET\ /news\.php\?
RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^news\.php /news/%1? [R=301,L]
If you're only concerned about search engines, you could create a robots.txt file containing:
User-agent: *
Disallow: /news.php
This will make sure that search engines don't follow the news.php links.
To fix your rewrite rules, you might try adding L to the first RewriteRule to make sure that mod_rewrite doesn't continue:
RewriteRule ^news/([0-9]+) /news.php?id=$1 [PT,L]
RewriteCond %{QUERY_STRING} ^id=([0-9]+)
RewriteRule ^news\.php /news/%1? [R=301,L]
try using L
[L]
instead of
[PT]
If [L] doesn't work for you, the issue might be separate internal requests (not sub-requests that you could halt with [NS]).
See here.
simplest answer just add a canonical link in your head of your html document, this will stop your duplicate content issue.

Tricky URL rewrite, regex .htaccess

I have a tricky issue redirecting some URLs internally for my site.
The situation is this, I currently have a URL like example.com/check/youtube.com which internally redirects to check.php?domain=youtube.com using the following mod_rewrite code:
Options +FollowSymlinks
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.(.*) [NC]
RewriteRule ^(.*)$ http://%1/$1 [R=301,NC,L]
RewriteRule ^offline offline.php [NC,L]
RewriteRule ^error error.php [NC,L]
RewriteRule ^check/(.*)$ check.php?domain=$1 [NC,L]
However I would also like to be able to redirect to check.php using a URL like example.com/youtube.com. Unfortunately it is just beyond me to figure it out.
I have a directory /assets/ with all the CSS, JS, etc. which shouldn't be affected.
Thanks
Try this rule:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^[^/.]+\.[^/]+$ check.php?domain=$0 [L]
This rule rewrites any request with a URL path of the form [^/.]+\.[^/]+ (a string that contains at least one dot but no slashes at all) that cannot be mapped to an existing file to your check.php.
As you want to redirect "example.com/youtube.com" does that mean you wish to redirect pretty much anything? What is specifically allowed to be passed, e.g. would I be allowed to pass "example.com/youtube.com/foobar.php" for a redirect to check.php?