I need help on rewriteRule for multiple parameters as follow:
sitename.com/project.php?t=value1&a=value2
to become
sitename.com/project/value2/value1
but somehow I was unable to resolve the problem and the page shown 500 Internal Server Error
my htaccess file:
DirectoryIndex index.php
Options -Indexes
<Files *htaccess>
Deny from all
</Files>
<files page>
ForceType application/x-httpd-php
</files>
<IfModule mod_rewrite.c>
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
#resolve .php file for extensionless php urls
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
RewriteRule ^cp/edit-agent/([^/\.]+)/?$ cp/edit-agent.php?name=$1 [L]
RewriteRule ^([^/\.]+)/?$ agent.php?name=$1 [L]
#rule to handle example.com/123/sys
RewriteRule ^project/([0-9]+)/([^/\.]+)/?$ project.php?a=$1&t=$2 [L,QSA]
</IfModule>
Please help.
You're rules look ok for the most part, but you have 2 problems. The first and most obvious problem is that you have 2 conditions that are only applied to the first rule:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
is only applied to this rule:
#resolve .php file for extensionless php urls
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]
When it also needs to be applied to this rule:
RewriteRule ^([^/\.]+)/?$ agent.php?name=$1 [L]
Conditions only get applied to the immediately following rule, so you need to duplicate them.
The other problem isn't so obvious, but this is probably what's causing the 500 error, is this condition:
RewriteCond %{REQUEST_FILENAME}\.php -f
THe problem is that you have requests like: /project/123/abcd and you have the file /project.php. The %{REQUEST_FILENAME} variable also takes into account PATH INFO, so if you just stick .php to the end, it will actually check: /project.php/123/abcd and PASS the -f check. BUt in the rule itself, you're appending it to the end, thus: project/123/abcd.php. Then the next time around, the same condition passes again, then .php gets appended to the end again: project/123/abcd.php.php, thus infinite loop.
So you need to change your rules to look like:
DirectoryIndex index.php
Options -Indexes -Mutiviews
<Files *htaccess>
Deny from all
</Files>
<files page>
ForceType application/x-httpd-php
</files>
<IfModule mod_rewrite.c>
Options +SymLinksIfOwnerMatch
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
#resolve .php file for extensionless php urls
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^(.*)$ $1.php [L]
RewriteRule ^cp/edit-agent/([^/\.]+)/?$ cp/edit-agent.php?name=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/\.]+)/?$ agent.php?name=$1 [L]
#rule to handle example.com/123/sys
RewriteRule ^project/([0-9]+)/([^/\.]+)/?$ project.php?a=$1&t=$2 [L,QSA]
</IfModule>
Related
I just did a huge makeover to a site and changed the framework. Because of that, the structure of urls changed. This is not a huge problem except for one url which is used a lot. I need to redirect user from the old address to the new one, and I just cannot figure out how to do that.
Old url: domain/?page/subpage/subsubpage.html?param=[parameter]/
New url: domain/controller/function/[parameter]/
My rewrite rules currently are this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php/$0 [L]
RewriteRule ^/\?page/subpage/subsubpage.html\?param=(.*)$ /controller/function/$1 [L]
but it does not work, no redirect is happening.
Edit: Added the whole htaccess file! This currently gives me error 500 ( "Request exceeded the limit of 10 internal redirects due to probable configuration error.")
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Allow asset folders through
RewriteRule ^(fuel/modules/(.+)?/assets/(.+)) - [L]
RewriteRule ^(fuel/modules/(.+)?/tuki/(.+)) - [L]
RewriteRule ^(fuel/modules/(.+)?/wiki/(.+)) - [L]
# Protect application and system files from being viewed
RewriteRule ^(fuel/install/.+|fuel/crons/.+|fuel/data_backup/.+|fuel/codeigniter/.+|fuel/modules/.+|fuel/application/.+) - [F,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/\?page/subpage/subsubpage.html\?param=(.*)$ /controller/function/$1 [L]
RewriteRule .* index.php/$0 [L]
# Prevents access to dot files (.git, .htaccess) - security.
RewriteCond %{SCRIPT_FILENAME} -d
RewriteCond %{SCRIPT_FILENAME} -f
RewriteRule "(^|/)\." - [F]
</IfModule>
Options -Indexes
With your shown samples/attempts could you please try following.
Please make sure you clear your browser cache before testing your URLs.
Options +FollowSymLinks
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine ON
RewriteBase /
<Files .*>
Order Deny,Allow
Deny From All
</Files>
# Prevents access to dot files (.git, .htaccess) - security.
RewriteRule \.(git|htaccess) - [F]
# Allow asset folders through
RewriteRule ^fuel/modules/(assets|tuki|wiki) - [L]
# Protect application and system files from being viewed
RewriteRule ^fuel/(install|crons|data_backup|codeigniter|modules|application)/.+ - [F,L]
##Any non existing directory OR files whose URI srarts from page rule.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/\?page/subpage/subsubpage.html\?param=(.*)$ /controller/function/$1 [L]
####If any non existing directory OR file is requested then come here:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ index.php/$0 [L]
###New rule added by me here.....
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
ReWriteCond %{QUERY_STRING} .*=([^/[]*)/?$
RewriteRule ^ controller/function/%1 [L]
</IfModule>
I am running a simple HTML site, with a .htaccess edit. I have several issues.
If I don't put https then - www.example.com/apply will redirect to https www.xyz.com/apply.html - I understand I have the https redirect on. However, I also have it so .html is removed.
https www.xyz.com/apply will load fine
https www.xyz.com/apply/ will give a 500 error because there is a / at the end
.htaccess code is as follows
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(([A-Za-z0-9\-]+/)*[A-Za-z0-9\-]+)?$ $1.php
<IfModule mod_headers.c>
<FilesMatch ".(js|css|xml|gz|html)$">
Header append Vary: Accept-Encoding
</FilesMatch>
</IfModule>
<filesMatch ".(css|jpg|jpeg|png|gif|js|ico)$">
Header set Cache-Control "max-age=2592000, public"
</filesMatch>
Any ideas? I wrote the code from memory so hopefully I'm not missing something.
Your problem is that you consider all wrong requests without / then you handle them like that , so you should check first whether a wrong request has / or not , then remove it internally , if you want a file look like directory,then handle it by the next rules , priority will be for html then to php so , your rules should look like this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
#as per your comment that all css files under /css directory i added the
#following rules
RewriteCond %{REQUEST_URI} !^/css
RewriteCond %{REQUEST_URI} \.css$
RewriteRule ^(.+)/css/(.*)$ /css/$2 [L]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^(.+)/$
RewriteRule ^ %1 [L,QSA]
RewriteCond %{REQUEST_FILENAME}\.html -f
RewriteRule ^(.+)$ $1.html [L,QSA]
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1.php [L,QSA]
NOTE: Clear browser cache the test .
Update:
If you want CSS files work while you adding / to files , there is a workaround , for example you put all CSS files in cssfolder directory , so when the request come to either html or php files without trailing slash , css will load normally like /cssfolder/file.css , but with trailing slash the path will be different /file/cssfolder/file.css , you could add rule to remove any request end with css that has any thing before cssfolder directory .
Like that :
RewriteCond %{REQUEST_URI} !^/cssfolder
RewriteCond %{REQUEST_URI} \.css$
RewriteRule ^(.+)/cssfolder/(.*)$ /cssfolder/$2 [L]
These rules above should be after RewriteEngine On at you rules above.
<Files ~ (\.php)>
Options +SymLinksIfOwnerMatch
</Files>
AddDefaultCharset utf-8
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+)/([0-9]+)$ index.php?lang=$1&menu=$2&submenu=$3 [L]
origin url: example.com/index.php?lang=de&menu=1&submenu=0
new url: example.com/de/1/0
new url load main page, but need another page
<Files ~ (\.php)>
Options +SymLinksIfOwnerMatch
</Files>
AddDefaultCharset utf-8
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+)/([0-9]+)$ index.php?lang=$1&menu=$2&submenu=$3 [L]
If you follow this, you told Apache to take everything that is not a file or a directory in the file system and rewrite it to index.php.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]
So that's what it is doing.
To make this do what you want, you have to make it like this:
<Files ~ (\.php)>
Options +SymLinksIfOwnerMatch
</Files>
AddDefaultCharset utf-8
RewriteEngine on
RewriteBase /
# if file/director does not exist, and if it matches the pattern
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([A-Za-z0-9-]+)/([0-9]+)/([0-9]+)$ index.php?lang=$1&menu=$2&submenu=$3 [QSA,L]
# then if it did not match the pattern, send it to index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ index.php [NC,L]
Note that you did not provide enough information to understand what you are actually trying to achieve. But my guess is it's something like this. I'm also assuming that you want to append the values to the query string of index.php (QSA), which is usually what you want.
But it's not really possible to guess further until you specify what all the urls are supposed to do.
Note that by matching anything not file/directory, and rewriting it without further argument as the last command to index.php (L), that ends the request processing, it will never hit the second case.
I've added the following to my .htaccess to properly redirect any visitors from http://domain.com to http://www.domain.com ... but I still can't get it to work with subpages...ie http://domain.com/subpage is not yet redirecting to http://www.domain.com/subpage .
Here is what I have in my htaccess now:
<Files wp-config.php>
order allow,deny
deny from all
</Files>
<Files .htaccess>
order allow,deny
deny from all
</Files>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
RewriteCond %{HTTP_HOST} !^www
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [L,R]
</IfModule>
So the question is what else would I need to add or update in my htaccess to get this working?
Many thanks for your suggestions!
You have the redirect happening after you've done routing to index.php, it needs to happen before any routing rules get executed. Try swapping them around:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^www [NC]
RewriteRule (.*) http://www.%{HTTP_HOST}/$1 [L,R]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
(also added the [NC] flag so case isn't checked in hostname match)
this is a snippet of my htaccess, at the bottom is the redirect for user accounts.
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(\.[a-zA-Z0-9]{1,5}|/|#(.*))$
RewriteRule ^(.*)$ /$1/ [R=301,L]
</IfModule>
Options -MultiViews
Options +FollowSymlinks
Options -Indexes
ErrorDocument 404 /core/error/templates/404/
AddDefaultCharset utf-8
AddCharset utf-8 .html .css .js .xml .json .rss .php
<IfModule mod_rewrite.c>
RewriteRule "(^|/)\." - [F]
</IfModule>
RewriteRule ^favicon.ico favicon.ico [NC,L]
# ----------------------------------------------------------------------
# RewriteRules
# ----------------------------------------------------------------------
# User profile redirect
#RewriteRule ^([^/]+)?$ /user/$1 [NC,R]
RewriteRule ^/([^/]+)/?$ profile.php?user=$1 [NC,L]
if i go to www.foo.bar/samsam it should populate the $_GET['user'] with "samsam" but when i do an echo it actually returns $_GET['user'] = profile.php
any ideas as to why its behaving this way?
You're close, but you need a couple of fixes to that last line. You'll need to remove the leading "/" character in your regexp. You'll also need to filter your last RewriteRule so it only affects non-existent files and directories. So... replace it with the following:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/?$ profile.php?user=$1 [NC,L]