Replace .php in URL with / using .htaccess - regex

I've been searching all day for a solution to replace .php in the URL with a / using .htaccess. Most of the solutions didn't work for me at all (didn't rewrite the URL, even just to remove .php) until I found this beautiful solution on SO.
https://stackoverflow.com/a/11084526/1724376
Now my issue is that it only removes the .php but does not replace it with a "/". I've tried many things with no luck but I don't know much about htaccess and rewrite conditions, etc. I'm really hoping someone here can help me.
Just so I don't get down-voted for not having tried anything, here's one that I tried but it didn't rewrite the URL at all.
RewriteCond /%{REQUEST_FILENAME}.php -f
RewriteRule ^([a-zA-Z0-9_-\s]+)/$ /$1.php
Help will be truly appreciated.
EDIT: To clarify, I want www.mysite.com/contact.php to show up as www.mysite.com/contact/

Have your rule like this:
RewriteEngine On
RewriteCond %{THE_REQUEST} \s/+(?:index)?(.*?)\.php[\s?] [NC]
RewriteRule ^ /%1/ [R=302,L,NE]
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ /$1.php [L]

Related

htaccess similar cases like Facebook or Twitter issue

I have this piece of line in my htaccess that causes errors. I couldn't find a similar answer to my inadequate wording.
I am attempting to get "username/followers, username/following, etc" and also "settings/account, settings/password, etc". I stopped using sub folders for non-scripts and images, so everything is on the same level.
Now I know they have similar casing, but I am curious how Facebook, Twitter, etc manage to do this.
Do they condense to one large page to make it work? I know they prevent people from using settings and other root level names from being used, and I haven't quite gotten to that point myself.
RewriteRule ^([^/]+)$ profile_home.php?userdomain=$1 [L]
RewriteRule ^([^/]+)/([^/]+)$ profile_home.php?userdomain=$1&selection=$2 [L]
RewriteRule ^settings/$ profile_settings.php [L]
RewriteRule ^settings/([^/]+)$ profile_settings.php?selection=$1 [L]
RewriteRule ^settings/([^/]+)/([^/]+)$ profile_settings.php?selection=$1&upload=$2 [L]
If I remove
RewriteRule ^([^/]+)/([^/]+)$ profile_home.php?userdomain=$1&selection=$2 [L]
Then everything works fine. How do I make this work with two pages?
I could do
RewriteRule ^settings/([^/]+)/$ profile_settings.php?selection=$1 [L]
But it doesn't look as nice. If not right place to ask, please let me know.
Your second rule matches both directory structures. You can use a negative lookahead so requests starting with the setting are not matched by that rule.
^(?!settings)([^/]+)/([^/]+)$
You can read more about lookaheads here:
http://www.rexegg.com/regex-lookarounds.html
http://www.regular-expressions.info/lookaround.html
Here is my solution
RewriteEngine On
# make sure to add your document root dir
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([\w-.]+)/?$ index.php?id=$1 [L,QSA]
RewriteCond %{DOCUMENT_ROOT}/htdocs/user/$2 -f
RewriteRule ^([\w-]+)/(.+)/?$ $2?id=$1&goto=$2 [L,QSA]
RewriteCond %{DOCUMENT_ROOT}/htdocs/user/$2/index.php -f
RewriteRule ^([\w-.]+)/([a-z0-9]+)/?$ $2/index.php?id=$1&goto=$2 [NC,L,QSA]
RewriteRule ^([\w-.]+)/([a-z0-9]+)/?$ index.php?id=$1&goto=$2 [NC,L,QSA]
so inside your server root dir htdocs/user/ you must have a folder like /user/ and a file index.php this htacess will replace the file site/user/index.php to site/user/username in the same user dir you need to have the following.php file so site/user/username/following.php in the same folder, I think you understand my answer.

RewriteRule in htaccess having no affect

Sorry, this is probably a simple issue but I've read tons of tutorials and can't solve the issue. Here's the URL sample:
http://localhost:8106/privacy-policy/?lang=fr&dest=app
The .htaccess contents:
RewriteEngine on
RewriteRule ^privacy-policy/?lang=([a-z][a-z])&dest=app$ privacy-policy/$1 [NC,L]
When I visit the URL I don't get redirected. Any ideas?
Thanks
You can't match against the query string in a rule, you need to use the %{QUERY_STRING} variable:
RewriteEngine on
RewriteCond %{QUERY_STRING} ^lang=([a-z][a-z])&dest=app$
RewriteRule ^privacy-policy/$ privacy-policy/%1 [NC,L]
Note that the backreference needs to be %1. If you need it to redirect the browser, you'll also need a R flag in the square brackets.
Thanks Jon Lin for the leads on the query_string and %1 edit. It didn't end up working with a copy/paste of that code but this is finally what I ended up with and it is working:
RewriteCond %{REQUEST_URI} privacy-policy
RewriteCond %{QUERY_STRING} lang=(\w+)&dest=app
RewriteRule ^privacy-policy/$ /privacy-policy/%1? [R=301,L]
Thanks again for your help on this.

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 rewriting to wrong page

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]

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