mod_rewrite - Send everything that doesn't exist to index.php - .htaccess

I would like to have my .htaccess file rewrite anything that doesn't exist to the index.php file. So for example: www.example.com/category/subcategory/product1/ would be rewritten to index.php?request=category/subcategory/product1
I want to perform a check to see if the directory exists first though, and if it does, do not rewrite. I have something like this at the moment, but just need to know how I can get the requested URL into the PHP $_GET variable:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) /index.php [L]
Advanced thanks for any help!

You are almost there:
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?request=$1 [L,QSA]
TBH, there is no real need to put requested URL into $_GET variable -- you can ALWAYS access original (requested) URL via $_SERVER['REQUEST_URI'] -- the only difference is that REQUEST_URI will always start with leading slash (e.g. /category/subcategory/product1).

Related

mod_rewrite: how to enable access to static content and redirect specific url schemes?

My apps' urls are like this: http://domain.com/projects/project-name/
My app's file system is like this:
htdocs/projects/project-name/
L index.html
L img/image1.png
L img/image2.png
L img/...
I need to send requests like http://domain.com/projects/project-name/ to
htdocs/index.php?section=$1&item=$2
But they display the project-name/index.html file instead.
Here is what i tried:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule . - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2&%{QUERY_STRING} [NC,L]
Obviously, the RewriteCond %{REQUEST_FILENAME} -frule is the culprit. But i need to let the server serve the static img files. How can I tell it to let all file requests but rewrite the project folder's default index.html?
It should work, I am providing a slightly modified version of your rule with complete .htaccess to be placed in DOCUMENT_ROOT/.htaccess:
DirectoryIndex index.php index.html
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?section=$1&item=$2 [L,QSA]
Edit: Misunderstood the question.
You want to rewrite /projects/project-name/ to index.php?... I am also assuming you'll want to be able to request files from within project-name:
RewriteEngine on
RewriteRule ^([^/]+)/([^/]+)(/(index[^/]+)?)?$ /index.php?section=$1&item=$2 [QSA,NC,L]
If being able to request files from the project-name subdir isn't important, just remove (/(index[^/]+)?) and replace it with /. The (/(index[^/]+)?) assumes your DirectoryIndex files start with "index".
Meh.
Consider enabling the mod_rewrite log to analyze how it is applying your conditions and patterns. Within the server or vhost scope (not htaccess) add:
LogLevel warn rewrite:trace6
The LogLevel directive can enable logging for mod_rewrite which will be written to your defined ErrorLog. trace6 is the highest mod_rewrite log level before you get into hex output. Be sure to comment out or remove LogLevel when you're done.
Original, unrelated answer (ignore):
You need to negate files, of which right now you are not, notice the use of !:
RewriteCond %{REQUEST_FILENAME} !-f
Most importantly, your RewriteCond will not affect your second RewriteRule. It is only applied to the first RewriteRule (in your case RewriteRule . - [L]):
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2&%{QUERY_STRING} [NC,L]
And you may also choose to negate directories:
RewriteCond %{REQUEST_FILENAME} !-d
I'd also consider using the QSA (query string append) flag instead of appending QUERY_STRING:
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2 [QSA,NC,L]
In summary:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]+)/([^/]+)/?$ index.php?section=$1&item=$2 [QSA,NC,L]

.htaccess rule not excluding existing files when rule has a slash condition

I am redirecting this type of url
http://www.site.com/windows/games/ or http://www.site.com/windows/games
http://www.site.com/windows/software/ or http://www.site.com/windows/software
to
http://www.site.com/windows/ct.php?ct=games
http://www.site.com/windows/ct.php?ct=software
Site structure
wamp/www/Site/windows/ct.php
I am trying this way its redirecting properly but when url has trailing slash at end its rewriting css, js files too.
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/([^/]*)/?$ /Site/windows/ct.php?ct=$1 [L]
i.e
this type of url has css and javascript applied.
http://www.site.com/windows/games
but this type of url has no css and javascript applied. (not working with trailing slash).
http://www.site.com/windows/games/
I have tried several syntax like
RewriteRule ^windows/([^/]+)/?$ /windows/ct.php?ct=$1 [L]
RewriteRule ^windows/(^(.[^/]*)/?)$ /windows/ct.php?ct=$1 [L]
RewriteRule ^windows/([^/]*)/? /windows/ct.php?ct=$1 [L]
RewriteRule ^windows/([^/]+)/? /windows/ct.php?ct=$1 [L]
but it didn't work.
Complete .htaccess
Options +FollowSymlinks -MultiViews
RewriteEngine on
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/([^/]*)/?$ /Site/windows/ct.php?ct=$1 [L]
RewriteRule ^[^/]*/[^/]*/(.*\.html) /Site/error/400/ [L]
RewriteRule ^(error) - [L]
RewriteRule ^sitemap\.xml$ sitemap.php [L]
RewriteRule ^rss/(.*?)\.xml$ rss/$1.php [L]
</IfModule>
ErrorDocument 404 /Site/error/404/
Please see and suggest any possible way to do it.
Thanks.
The issue here is that your relative paths break when you add a trailing slash as it introduces two-levels of directory structure while the CSS/JS file paths come out only once ... So, your RewriteRule is actually firing for CSS/JS files as well when resolving 404s for paths like /windows/global/js/js.js. But, the scripts still fail to work because they aren't under /Site and that's where your rule is serving the request from.
So, to fix things without touching the relative URLs or resource locations; add another rule as follows:
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/([^/]*)/?$ /Site/windows/ct.php?ct=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^windows/(global/.*)$ /$1 [L] # handles css|js files
The rest of your .htaccess (of course) remains the same.
I use the following rule in .htaccess, but this may be too general:
RewriteRule ^q/([^/]+)/([^/]+)(\/?)$ /path/to/q.php?type=$1&q=$2&{QUERY_STRING} [NC]
This may be better for you:
RewriteRule ^windows(\/?)$ /path/to/windows.php?{QUERY_STRING} [NC]
RewriteRule ^windows/([^/]+)(\/?)$ /path/to/windows.php?type=$1&{QUERY_STRING} [NC]
You will have to change this according to your situation. I haven't tested this, but I hope it is good enough for you to get where you want.

Configure htaccess to load static pages

Im working on a server with the following htaccess:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule .* index.php
RewriteRule ^[^/]*\.html$ index.php
RewriteRule ^/(typo3|typo3temp|typo3conf|t3lib|tslib|fileadmin|uploads|showpic\.php)/ - [L]
RewriteRule ^/(typo3|typo3temp|typo3conf|t3lib|tslib|fileadmin|uploads|showpic\.php)/.*$ - [L]
Now they asked me to prepare a static page inside their server, lets call it http://www.myserver.com/mystaticpage.html
The problem is that when i try to access that url, it redirects to index.php. How could I alter the htacces file to address this problem without messing anything with the installed CMS?
Try this:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond ${REQUEST_URI} !^/(typo3|typo3temp|typo3conf|t3lib|tslib|fileadmin|uploads|showpic\.php)
RewriteRule .* index.php
The rules you used before were redundant: if .* is rewritten to index.php then why also rewrite ^[^/]*\.html$ index.php to it? it already matched previous rule...
They also overlapped - since the three RewriteCond conditions were only applied on the first rule. So the second rule was also applied to static files on disk.
Also, the two rules that were listed last had no effect whatsoever. Either you needed to list them first, or not at all. I converted them to an additional RewriteCond since they were only attempted to avoid rewrite on certain uris

mod rewrite with dots

i want to change a url like : localhost/site/home.php?p=index to localhost/site/index
i use this code in my htaccess file
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ home.php?p=$1 [L,NS]
but when i write like localhost/site/home.php?p=profile.user i get the 404 error, and go to this link
localhost/profile.user
so how can i fix itthanks
Let's look at your rewrites first:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ home.php?p=$1 [L,NS]
This is relative rewrite: the replacement text home.php... does not begin with a slash. Relative rewrites in a per-directory context (<Directory> or .htaccess) require a RewriteBase directive to be configured, otherwise they do the wrong thing.
Secondly, your rule is backwards, If you want to rewrite the home.php URL to the site/index one, you have to put the home.php match on the left side, and the site/index on the right:
RewriteRule ^home.php?p=(.*) /site/$1
Notice that I have an absolute rewrite. This means that mod_rewrite will create a URL out of the rewrite by sticking http://example.com on it. A new request is internally generated now for http://example.com/site/<whatever>. We can get away without using RewriteBase since we have no relative rewrites.
As for your last question, it is not clear why when you access localhost/site/home.php?p=profile.user you're being taken to localhost/profile.user. I'm suspecting that it's your home.php script doing that, perhaps. You're trying to use mod_rewrite to hijack that particular kind of PHP request and send it elsewhere, right?
What you meant is probably: you want to rewrite this way:
http://mysite.com/index => http://mysite.com/home.php?p=index
So this should work
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^/?$ /home.php?p=$1 [QSA,L]
Now if you want the opposite:
http://mysite.com/home.php?p=index => http://mysite.com/index
This should work:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule /home\.php$ / [QSA,L]

mod_rewrite - do two redirects - if the first one dosen't match do the second

This is my htaccess file at the moment
RewriteEngine On
# Only redirect if file dosen't exist.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^admin/(.*) /admin.php
RewriteRule ^([^/]) /index.php [L]
I don't have any idea why this doesn't work. I think I've finally grasped mod_rewrite and then it just does something completely unexpected like this.
Basically if the URL is domain.com/admin/something then I want it to redirect to domain.com/admin.php (including if its just /admin). However if its ANYTHING else I want it to redirect to index.php.
Any idea how to achieve this?
Thank you.
RewriteEngine On
# No redirect, if file or directory exists
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .* - [L]
RewriteRule ^admin/(.*) /admin.php [L]
RewriteRule ^(.*)$ /index.php [L]
Didnt test it. The interesting part is the L-Flag after the admin-rule, because it prevents the next rule from matching.
I changed the RewriteCond-Statements, because they only apply to the one next RewriteRule and (in your case) doesnt affect the rule to index.php.

Resources