.htaccess Get Parameters to index.php - apache

How can I redirect every request to index.php?
I also want the first 5 parameters as Get values.
Etc. /foo/bar/melon/car/berry/ would request index.php/?one=foo&two=bar&three=melon&four=car&five=berry (if only /foo/bar/ three, four and five would be empty etc.)
Is this possible and how?

You can use this code in your DOCUMENT_ROOT/.htaccess file:
RewriteEngine On
RewriteBase /
# skip all files and directories from rewrite rules below
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/?$ index.php?one=$1 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?one=$1&two=$2 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/?$ index.php?one=$1&two=$2&three=$3 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ index.php?one=$1&two=$2&three=$3&four=$4 [L,QSA]
RewriteRule ^([^/]+)/([^/]+)/([^/]+)/([^/]+)/([^/]+)/?$ index.php?one=$1&two=$2&three=$3&four=$4&five=$5 [L,QSA]

Related

mod_rewrite omit html extension loop

I have the following scenario:
Two frontcontrollers in a web directory (document root):
web/frontend.php # handles all *.html requests
web/backend.php # direct calls only
Rewriting is easy so far:
RewriteCond %{REQUEST_URI} !^/backend.php
RewriteRule (.+)\.html$ /frontend.php [L]
So now when I call example.org/backend.php I'm in the backend, nothing special happens. And when I call something like example.org/ or example.org/team/john.html it is handled by frontend.php.
Works so far!
Now I want the possibility to omit the *.html extension so that example.org/team/john is internally handled as example.org/team/john.html.
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_URI}.html [L]
Last but not least I want to redirect requests to john.html to john to avoid duplicate content.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} ^(.+)\.html$
RewriteRule (.*)\.html$ /$1 [R=301,L]
Every part works on it's own but put together I get a loop, which doesn't surprise me but I don't know how to avoid this. I searched the docs, tried several flags and conditions but I'm totally stuck and I need help.
Here is the whole .htaccess file:
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
# extend html extension internally
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_URI}.html [L]
# redirect example.html to example
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} ^(.+)\.html$
RewriteRule (.*)\.html$ /$1 [R=301,L]
# frontcontroller
RewriteCond %{REQUEST_URI} !^/backend.php
RewriteRule (.+)\.html$ /frontend.php [L]
</IfModule>
Any help would be great.
To avoid a loop, you can use THE_REQUEST
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{THE_REQUEST} "\.html "
RewriteRule ^(.*)\.html$ /$1 [R,L]
Unrelated, but you can simplify your rules. First one
RewriteCond %{REQUEST_URI} !^/backend.php
RewriteRule (.+)\.html$ /frontend.php [L]
You already check for (.+)\.html, so you can omit the RewriteCond. Next, you don't use the captured part (.+). Replace it with . to ensure it's not empty. This gives then
RewriteRule .\.html$ /frontend.php [L]
Second one, unless you have *.html.html files in your site, you don't need to check for !html and can just use ^ for the RewriteRule pattern
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^ %{REQUEST_URI}.html [L]
The loop is because of the multiple internal redirections, You can use END flag to prevent the rewrite loop
RewriteRule ^(.+)\.html$ /$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule !.*\.html$ %{REQUEST_URI}.html [END]

.htaccess URL re-write - strip .php suffix

I want to rewrite URLs like this:
http://domain.com/category.php?id=xx
to:
http://domain.com/category/?id=xx
Also, I want to hide the index.php. How can I achieve this with .htaccess? The following code doesn't work:
##REDIRECTS-START
##REDIRECTS-END
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(ADMIN.*) $2 [L]
RewriteRule ^([_0-9a-zA-Z-]+/)?(.*\.php)$ $2 [L]
### ROOT DIR TO PROJECT
RewriteRule . wallkill/index.php [L]
Thanks.
Try this code
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*)$ $1.php [NC,L]
reference link
You need 2 sets of rules. The first set redirects the browser to requests without the .php at the end, then internally rewrites the .php back. The second rule redirects the browser to requests without the index.php.
So something like:
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /+(.*)index\.php
RewriteRule ^ /%1 [L,R]
RewriteCond %{THE_REQUEST} \ /+([^\?]+)\.php
RewriteRule ^ /%1/ [L,R]
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ /$1.php [L]
Note that when you add that / trailing slash to the end, your relative URL base changes, and all your relative links will break. To fix this, either make sure all your links are absolute (start with / or http://) or add a relative base to the header of all your pages:
<base href="/" />

htaccess on multidomain setup: other domains don't work

I have a multidomain setup that looks like this on my server … this is a model of the structure:
.htaccess
***my-website
.htaccess
index.php
projects.php
jobs.php
some-project.php
another-project.php
some-job.php
another-job.php***
other-domain
other-domain
other-domain
I have two goals:
1.) The root .htaccess file should just make sure, that my main-domain which is /my-website is run/executed automatically when entering www.my-website.com. Due to the fact that I have a multidomain ftp-server I need do specify that. That is working already.
2.) In my sub-directory /my-website I need some different rules, especially regarding better url design and the omittance of .php extension.
So in /my-website I want to neglect all .php suffixes.
And I want to "fake" directories like /jobs /projects which are actually not directories but php-files themselves.
This is what I have so far thanks to #anubhava in this thread.
DocumentRoot/.htaccess:
RewriteEngine On
RewriteBase /
RewriteRule ^projects/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^jobs/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^(downloads/.+)/?$ assets/$1 [L,NC]
# add .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
RewriteCond %{REQUEST_URI} !^/my-website/
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -d
RewriteRule ^(.*)$ /my-website/$1 [L]
/my-website/.htaccess:
RewriteEngine On
RewriteBase /my-website/
# add .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/my-website/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
However I have the problem now when using this, that in my-website the links without a trailing .php wont work. I want my links to work like /projects but run/exectute /projects.php in my-website. However this doesn't work at the moment, i get a 404.
I also want /projects/some-project to run/execute /some-project.php (where the projects directory doesn't actually exist) which doesn't work either, also 404.
So, to sum it up.
All my domains work now! So my multidomain-setup is save and handeld.
However inside /my-website I want all links to work without trailing .php and with this "faked" directories
So right now this works …
www.my-website.com // works
www.other-domain.com // works
www.my-website.com/projects // doesn't work without trailing .php
www.my-website.com/projects.php // works (runs projects.php)
www.my-website.com/projects/some-project // doesn't work (should run some-project.php)
www.my-website.com/projects/some-project.php // works (runs some-project.php)
Have root .htaccess like this:
RewriteEngine On
RewriteBase /
## COMMENT out these 2 rules
# RewriteRule ^projects/(.+?\.php)$ /$1 [L,NC]
# RewriteRule ^jobs/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^(downloads/.+)/?$ assets/$1 [L,NC]
# add .php extension
RewriteCond %{DOCUMENT_ROOT}/my-website/$1\.php -f [NC]
RewriteRule ^(?:[^/]+/)?([^/]+)/?$ my-website/$1.php [L]
RewriteCond %{HTTP_HOST} ^(www\.)?my-website\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/my-website/ [NC]
RewriteRule ^(.*)$ my-website/$1 [L]
# add .php extension 2
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(?:[^/]+/)?([^/]+)/?$ $1.php [L]
/my-website/.htaccess:
RewriteEngine On
RewriteBase /my-website/
# add .php extension
RewriteCond %{DOCUMENT_ROOT}/my-website/$1\.php -f [NC]
RewriteRule ^(?:[^/]+/)?([^/]+)/?$ $1.php [L]
DocumentRoot/.htaccess:
RewriteBase /
RewriteRule ^projects/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^jobs/(.+?\.php)$ /$1 [L,NC]
RewriteRule ^(downloads/.+)/?$ assets/$1 [L,NC]
# add .php extension for REQUEST_FILENAME existing in /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f [NC]
RewriteRule ^(.+?)/?$ $1.php [L]
# Check if REQUEST_URI is existing as file or directory in /my-website
RewriteCond %{REQUEST_URI} !^/my-website/
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI} -d
RewriteRule ^(.*)$ /my-website/$1 [L]
# Check if REQUEST_URI is existing as file.php in /my-website
RewriteCond %{REQUEST_URI} !^/my-website/
RewriteCond %{DOCUMENT_ROOT}/my-website%{REQUEST_URI}.php -f
RewriteRule ^(.*)$ /my-website/$1 [L]
/my-website/.htaccess:
RewriteEngine On
RewriteBase /my-website/
# To internally forward /dir/foo to /dir/foo.php
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

Apache mod_rewrite infinite loop, cannot fix it

My htaccess:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ([^/.]+)/([^/.]+)(.*) /Application/?path=$1/$2$3 [L,QSA]
RewriteRule ^$ /Application/?path=ACFrontPage/getMainPage [L,QSA]
RewriteRule (.*) /Application/index.php?path=$1 [L,QSA]
This line causes infinite redirect:
RewriteRule (.*) /Application/index.php?path=$1 [L,QSA]
But I need if previous rules didn't match, to redirect everything to index.php file.
How can I do it?
From logs its doing this:
split uri=/Application/?path=Application/ -> uri=/Application/, args=path=Application/&path=Application/&path=Application/&path=Application/&path=Application/&path=Application/&path=Application/&path=Application/&path=Application/&path=Application/
========================
#anubhava
I tried your suggested answer and it works for everything except base domain i.e.:
http://example.com/
RewriteCond is only applicable to very next RewriteRule. Tweak your rules to avoid rewrites for all existing file or directories:
RewriteEngine On
RewriteRule ^$ /Application/?path=ACFrontPage/getMainPage [L]
# skip rewrite for all files/directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^([^/.]+)/([^/.]+)(.*)$ /Application/?path=$1/$2$3 [L,QSA]
RewriteRule ^(.+)$ /Application/index.php?path=$1 [L,QSA]

htaccess calling rewrite rule on everything

This is my htaccess file:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Static pages
RewriteRule ^print/([0-9]+)$ index.php?action=PublicDisplayPrint&page_id=$1 [L,QSA]
RewriteRule ^email/([0-9]+)$ index.php?action=PublicDisplayEmail&page_id=$1 [L,QSA]
RewriteRule ^login$ index.php?action=PublicDisplayLogin [L,QSA]
RewriteRule ^search$ index.php?action=PublicDisplaySearch [L,QSA]
RewriteRule ^feedback$ index.php?action=PublicDisplayFeedback [L,QSA]
RewriteRule ^sitemap$ index.php?action=PublicDisplaySitemap [L,QSA]
# Dynamic pages
RewriteRule ^(.*)$ index.php?action=PublicDisplayPage&url=$1 [L,QSA]
It seems to be calling the dynamic page rule on any file (logo.gif for example) so it doesn't seem to be running the 2nd and 3rd line. Any ideas?
The condition of a RewriteCond directive does only belong to the first following RewriteRule directive. So in this case the two RewriteCond conditions do only apply to the first RewriteRule and not to the other rules, especially not to the last rule.
So put the RewriteCond directives immediately in front of the the last RewriteRule directive:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?action=PublicDisplayPage&url=$1 [L,QSA]
The RewriteConds are applicable only to the next following RewriteRule so your last 7 rules will be applied to any request.
You could either repeat the condition for each rule, put it on the last rule or put an explicit rule to serve the content as is (this is more flexible because allows you to add more dynamic rules later):
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
#If it's a file or directory, serve as is, without rewriting
RewriteRule ^ - [L]
#Rest of the rules