.htaccess eg.php?id=3 to eg/id/3 - apache

Problem:
I know there are alot of examples like the title on the web, but non of them work properly for me. How do I get my .htaccess to rewrite AND redirect ALL pages like /eg.php?id=3 to /eg/id/3 and /eg.php to /eg
My current .htaccess
ErrorDocument 404 /404.php
<Files .htaccess>
order allow,deny
deny from all
</Files>
RewriteEngine On
EDIT (WORKS)
RewriteEngine On
RewriteRule ^/?([^/]+)/id/([0-9]+)$ $1.php?id=$2 [L,QSA]
RewriteCond %{HTTP_HOST} ^www\.(.*)$ [NC]
RewriteRule ^(.*)$ http://%1%{REQUEST_URI} [R=301,QSA,NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [NC,L]
ErrorDocument 404 /404.php
<Files .htaccess>
order allow,deny
deny from all
</Files>
Fixes StyleSheet errors:
<head><base href="http://website.com/"></head>

I'd say that should do what you ask for:
RewriteEngine on
RewriteRule ^/?eg/id/([0-9]+)$ eg.php?id=$1 [L,QSA]
RewriteRule ^/?eg/?$ eg.php [L,QSA]
Obviously the interpretation of .htaccess style files has to be enabled and the rewriting module has to be loaded for this to work.
This is a more general version as asked in the comments below:
RewriteEngine on
RewriteRule ^/?([^/]+)/id/([0-9]+)$ $1.php?id=$2 [L,QSA]
RewriteRule ^/?([^/]+)/?$ $1.php [L,QSA]
This further version should redirect requests still carrying a .php ending to their new versions:
RewriteEngine on
RewriteCond %{QUERY_STRING} (.*)(?:^|&)id=([^&]*)((?:&|$).*)
RewriteRule ^/?([^/]+)\.php$ $1/id/%2 [L,R=301,QSA]
RewriteRule ^/?([^/]+)\.php$ $1 [L,R=301,QSA]
RewriteRule ^/?([^/]+)/id/([0-9]+)$ $1.php?id=$2 [L,QSA]
RewriteRule ^/?([^/]+)/?$ $1.php [L,QSA]
And a general hint: you should always prefer to place such rules inside the http servers host configuration instead of using .htaccess style files. Those files are notoriously error prone, hard to debug and they really slow down the server. They are only provided as a last option for situations where you do not have control over the host configuration (read: really cheap hosting service providers) or if you have an application that relies on writing its own rewrite rules (which is an obvious security nightmare).

Related

htaccess RewriteRule with a variable not working

This rule takes us to the error page
RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]
I have the following in my .htaccess file
<IfModule mod_rewrite.c>
RewriteRule ^sucuri-(.*)\.php$ - [L]
</IfModule>
# END - Allow Sucuri Services
<Files 403.shtml>
order allow,deny
allow from all
</Files>
ErrorDocument 404 /404.php
Options +FollowSymLinks
Options +MultiViews
RewriteEngine on
RewriteCond %{HTTPS} !=on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
RewriteCond %{HTTP_HOST} !^www.xxxxx.com$ [NC]
RewriteRule ^(.*)$ https://www.xxxxx.com/$1 [L,R=301]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]
## Remove php extension
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteRule ^([^\.]+)$ $1.php [NC,L]
RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]```
With the following rule
```RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]```
Trying to achieve the following -
```https://www.xxxxx.com/latest?auth=US-mobile-county
to
https://www.xxxxx.com/latest/US-mobile-county```
This rule takes us to the error page RewriteRule ^latest/([A-Za-z0-9]+)$ latest?auth=$1 [NC,L]
You've not stated precisely what "error page" you are referring to? Or what is expected to handle this request. This directive is not correct by itself, so it's not immediately clear what it is you are trying to do. I'm assuming the intention is to rewrite to latest.php (not latest as suggested by this rule, and mentioned later in the question) - since this would seem to be the only reason to implement such a rule (and your question is tagged php). By rewriting to latest only you are dependent on other directives appending the .php extension - and therein lies a conflict.
There are a number of issues with the directives as posted that is preventing this from working. Notably, the rules are in the wrong order and the use of MultiViews (probably in an attempt to get extensionless URLs working) is compounding matters. In fact, it doesn't look like the rule in question is actually being processed at all.
Without MultiViews, and due to the order of the directives, a request of the form /latest/something would be rewritten to /ci_index.php?/latest/something (presumably a CodeIgniter front-controller) which I would guess would result in a CI generated 404 response. However, since MultiViews has been enabled mod_negotiation first "rewrites" the request to /latest.php/something, which doesn't match any of your rules so either results in a 404 (depending on your server config) or calls latest.php but without any URL parameter, which presumably causes your script to fail?
https://www.xxxxx.com/latest/US-mobile-county
Also, note that your example URL contains hyphens (-), but the regex in your directive (ie. ^latest/([A-Za-z0-9]+)$) does not permit hyphens so it wouldn't have matched anyway.
Try the following instead, replacing everything after the ErrorDocument directive:
# Disable MultiViews
Options +FollowSymLinks -MultiViews
RewriteEngine on
# Redirect HTTP to HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Redirect non-www to www
RewriteCond %{HTTP_HOST} !^www\.example\.com [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L]
# Rewrite "/latest/something" to "/latest.php?auth=something"
RewriteRule ^latest/([A-Za-z0-9-]+)$ latest.php?auth=$1 [L]
# Allow extensionless PHP URLs to work
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^.]+)$ $1.php [L]
# Front-controller
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ ci_index.php?/$1 [L]
Note that I've reversed the order of the directives so that the rule in question is now first and the CI front-controller is now last. The order of the directives in .htaccess is important.
Since you had enabled MultiViews (now disabled in the above), your rule to enable PHP extensionless URLs (that you had labelled "Remove php extension") was not actually being used at all (unless you had directories or files that contained dots, other than that used to delimit the file extension).

.htaccess RewriteRule with existing file and folder

My web structure looks like this:
public_html/
/images/
/user/
/userimage1.jpg
/userimage2.jpg
/userimage3.jpg
/icons/
/index.php
/user.php
...
I have 2 domains: example.com and images.example.com and I want to use a .htaccess RewriteRule that the images.example.com subdomain leads to the /images/-folder but also to use URLs without the file extension.
My .htaccess looks like this:
<IfModule mod_rewrite.c>
Options +FollowSymLinks +MultiViews
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} ^images\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/images/
RewriteRule ^(.*)$ /images/$1 [NC,L]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.php -f
RewriteRule ^(.*)$ $1.php [L]
</IfModule>
Now, https://example.com/user/ works fine, but when I try to open https://images.example.com/user/userimage1.jpg it says that %{REQUEST_URI} is /images/redirect:/images/user.php/userimage1.jpg
Unfortunately, both, the domain and the subdomain have to be installed with public_html as the root folder.
How do I have to adept my .htaccess file so that both URLs, https://example.com/user/ and https://images.example.com/user/userimage1.jpg work fine?
You have a conflict with MultiViews (which you've enabled at the top). The fact that "https://example.com/user/ works fine" (with a trailing slash) is because of MultiViews, not because of your mod_rewrite directives. (The mod_rewrite directives as written would only "work" with /user - no trailing slash.)
When you request https://images.example.com/user/userimage1.jpg, MultiViews triggers an internal subrequest for /user.php/userimage1.jpg (/user.php with additional path-info /userimage1.jpg), but mod_rewrite has also tried to rewrite the request (an internal "redirect") - hence the seemingly malformed rewrite.
Generally, you need to avoid using MultiViews with mod_rewrite rewrites - a common cause of conflict.
Try the following instead:
Options +FollowSymLinks -MultiViews
RewriteEngine on
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
# Rewrite images subdomain
RewriteCond %{HTTP_HOST} ^images\.example\.com$ [NC]
RewriteCond %{REQUEST_URI} !^/images/
RewriteRule ^(.*)$ /images/$1 [L]
# Append .php file extensions
RewriteCond %{DOCUMENT_ROOT}/$1 !-d
RewriteCond %{DOCUMENT_ROOT}/$1\.php -f
RewriteRule ^(.*)/$ $1.php [L]
Note that I've included the trailing slash in the RewriteRule pattern and taken this out of the capturing subpattern - this is assuming that the trailing slash is mandatory on your URLs (as in your example).
You don't need the <IfModule> wrapper unless mod_rewrite really is optional? (It's not.)

Symfony2: simple rewrite rule in vhost to strip .html extention out

Since I migrated my project on Symfony2, I also avoided to use .html extensions previously used for my generated urls.
So, after looking at some examples, I'am trying to execute this in my /etc/apache2/sites-available/mysite:
<IfModule mod_rewrite.c>
Options -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)\.html$ $1 [NC,L]
#this is the standard rewrite rule to redirect every request to /web/app.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ app.php [QSA,L]
</IfModule>
I have tried many combinations but no one seems to work. Any Help? Thanks

htaccess and CakePHP3 routing (multiple "sites" same server)

Okay so I need just a little bit of help, I think i almost have my routing clean but am running into one small issue.
I am trying to setup one server to handle multiple different static sites as well as a cakephp 3 installation.
The root .htaccess has the following
Options +FollowSymLinks
RewriteEngine on
RewriteCond %{ENV:REDIRECT_SUBDOMAIN} =""
RewriteCond %{HTTP_HOST} ^(www\.)?([a-z0-9][-a-z0-9]+)\.domain\.com(:80)?$ [NC]
RewriteCond %{HTTP_HOST} !^www\.domain\.com
RewriteCond %{DOCUMENT_ROOT}/%2 -d
RewriteRule ^(.*) /%2/$1 [E=SUBDOMAIN:%2,L]
RewriteRule ^ - [E=SUBDOMAIN:%{ENV:REDIRECT_SUBDOMAIN},L]
This works great for routing subdomains to their proper folder
static.domain.com properly goes to /static/index.php
the problem comes when i try to access my cake installation
cake.domain.com ends up routing to cake.domain.com/cake/$1
I really need it to route to cake.domain.com/$1
/cake/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /cake
RewriteRule ^$ webroot/ [L]
RewriteRule (.*) webroot/$1 [L]
</IfModule>
/cake/webroot/.htaccess
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /cake
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !^/(webroot/)?(img|css|js)/(.*)$
RewriteRule ^ index.php [L]
</IfModule>
I will be eternally grateful for any help, i have exhausted google searching and banging my head on the wall.
I am completely open to easier ideas as well

Allow URLs without any extension with url rewriting, like exemple.com/forum

I need to allow urls like http://example.com/forum on my website.
Here is my .htaccess :
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^([a-z-]+)$ /$1.php [L]
Currently, I get a 404 error.
If I change ^([a-z-]+)$ /$1.php [L] to ^([a-z-]+).html$ /$1.php [L], and my url http://example.com/forum.html, it works.
I want something like stackoverflow, http://stackoverflow.com/questions
EDIT: It works with WAMP in localhost, but on the website, it doesn't.
What's missing?
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
# add .php file extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule (.+) /$1.php [L,QSA]
I have added Options -MultiViews -- can make a big difference on some configurations (possibly your case).
Rule is now also checking if such .php file actually exist. If not -- no rewrite occurs.