.htaccess: mod_rewrite - .htaccess

Here is what I'm trying to accomplish:
(this .htaccess file is located in mysite.com/test/):
http://mysite.com/test/admin go to http://mysite.com/test/admin/index.php
http://mysite.com/test/contact go to http://mysite.com/test/contact.php
http://mysite.com/test/salt-lake-city/ go to http://mysite.com/test/index.php/city=salt-lake-city
http://mysite.com/test/salt-lake-city/deals/ go to http://mysite.com/test/deals.php?city=salt-lake-city
To start, I have:
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
(this handles the last 2). But, when I try to add the admin clause:
RewriteRule ^admin/ admin/index.php [L]
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
It messes up (the css is out of whack) etc.
Any thoughts?

Well .. if I had to do these rewrite rules, I would do them like this:
Options +FollowSymLinks -MultiViews
RewriteEngine On
# do not do anything for already existing files
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule .+ - [L]
# admin rewrite
RewriteRule ^admin$ admin/index.php [L]
# rewrite /contact --> /contact.php (and similar)
# add .php extension if such file does exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.+)$ $1.php [L]
# OR
# alternatively specify their names directly
# plus it is more precise for the example you have provided
# (that's if you need to rewrite only specific pages)
RewriteRule ^(contact|about|something)$ $1.php [L]
# /salt-lake-city/ --> /index.php?city=salt-lake-city
RewriteRule ^([^/]+)/$ index.php?city=$1 [QSA,L]
# /salt-lake-city/deals/ --> /deals.php?city=salt-lake-city
RewriteRule ^([^/]+)/deals/$ deals.php?city=$1 [QSA,L]
To start, I have:
RewriteRule ^(.*)/(.*)\.php$ $2.php?city=$1 [L]
(this handles the last 2).
Sorry, but I do not see how "it will handle the last 2". I see no .php in the last two URL examples you have provided.
It messes up (the css is out of whack) etc.
Well -- let's see how it will work with my rules. In any case -- it may also depends how you wrote links to css/images/js.

Related

htaccess redirecting to the wrong page when using multiple rewriterules

I have a htaccess file which looks like the following:
Options -Indexes
RewriteEngine On
# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# only allow rewriting to paths that dont exist
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
# example.com/username
RewriteRule ^([\w\d_\-]+)/?$ profile.php?uid=$1 [L,QSA]
# example.com/username/$tab
RewriteRule ^([\w\d_\-]+)\/([\w]+)/?$ profile.php?uid=$1&tab=$2
# example.com/listen/$id
RewriteRule ^listen\/([\w\d_\-]+)?\/?([\w\d_\-]+)?$ track.php?id=$1&secret=$2 [L,QSA]
The way it is supposed to work is to redirect any URL looking like these:
1. example.com/example points to profile.php?id=example
or
2. example.com/example/tab points to profile.php?id=example&tab=tab
3. example.com/listen/example points to track.php?id=example
or
4. example.com/listen/example/code points to track.php?id=example&secret=code
The problem is that sometimes, a link which looks like the third one will point to the profile page. However, what's weirder, is that if example has a dash in it, it will point to the right place. This shouldn't be happening because my regex is matching after listen.
All help is appreciated.
Both of your listen/ rules should appear before other rules and moreover 2 RewriteCond are only being applied to next immediate RewriteRule.
You may use these rules to replace all of your code:
Options -Indexes
RewriteEngine On
# only allow rewriting to paths that don't exist
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# example.com/listen/$id
RewriteRule ^listen/([\w-]+)/?$ track.php?id=$1 [L,QSA,NC]
# example.com/listen/$id/secret
RewriteRule ^listen/([\w-]+)/([\w-]+)/?$ track.php?id=$1&secret=$2 [L,QSA,NC]
# no php extension
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
# example.com/username
RewriteRule ^([\w-]+)/?$ profile.php?uid=$1 [L,QSA]
# example.com/username/$tab
RewriteRule ^([\w-]+)/([\w-]+)/?$ profile.php?uid=$1&tab=$2 [L,QSA]
Also note that \w means [a-zA-Z0-9_] so no need to add \d_ in character class.

How can I rewrite a 'subfolder' to a script?

I need to redirect a URL example.com/servers/1/ to a PHP script (example.com/serverinfo.php) that recieves the 1 part of the requested URL as a GET variable (or similar).
I currently have a rule RewriteRule ^([^/.]+)$ $1.php that rewrites URLs such as example.com/servers to example.com/[file].php, and tried to base the following rule off that:
RewriteRule ^/?servers/([0-9]+)$/ /serverinfo.php$
The new rule has no effect (other than causing the page's CSS to fail to load), what am I doing wrong?
You can use:
Options -MultiViews
RewriteEngine On
# handle /servers/123
RewriteRule ^/?servers/([0-9]+)/?$ /serverinfo.php?num=$1 [L,QSA,NC]
# add .php extension
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+?)/?$ $1.php [L]

Rewrite rule in htaccess is not working

Here are the .htaccess rules:
RewriteEngine On
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap.xml$ xmlsitemap.php [L]
Options -Indexes
Here every URL is pointing to content.php?seourl=$1, even css, js and image files.
Here are some example URLs I need,
http://example.com/sjskjfsk21
http://example.com/asfasfasf43sf
http://example.com/pdf/fhfdhdh3432aaf
http://example.com/pdf/aisfyiahm2faf3
http://example.com/browsepdf
http://example.com/browsepdf-1
http://example.com/browsepdf-2
http://example.com/download/fjaskfjalsk3rs
http://example.com/download/usaydiy7aisydi
http://example.com/sitemap.xml
Can anyone please fix the .htaccess file.
Here every url is pointing to "content.php?seourl=$1"
Because your first (generic) rule catches all the requests. You need to change the order so you have the most specific rules first, and the most generic (catch-all) rules at the end. In your case you just need to move the first rule to the end. For example:
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap\.xml$ xmlsitemap.php [L]
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]
NB: I backslash-escaped the dot in sitemap.xml to match a literal dot, otherwise it matches any character.
even css, js and image files.
You can make an exception for these static resources at the beginning of your file, before the existing directives. For example:
RewriteRule \.(js|css|png|jpg|gif)$ - [L]
For any URL that ends in any of the stated file extensions then stop processing the current mod_rewrite rules.
Alternatively (although perhaps marginally less efficient), you can prevent processing of requests for files that exist. Again, this goes before your existing mod_rewrite directives. For example:
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
However, this must now check every request for the existence of a file on the filesystem that maps to the request. (It could also be combined with the above rule if required.)
UPDATE: Bringing this together, we have:
# Exclude any existing files from being rewritten
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Specific rewrites
RewriteRule ^pdf/([^/]*)$ content-single.php?seourl=$1 [L]
RewriteRule ^browsepdf$ browse.php [L]
RewriteRule ^browsepdf-([^/]*)$ browse.php?page=$1 [L]
RewriteRule ^download/([^/]*)$ download.php?pdf=$1 [L]
RewriteRule ^sitemap\.xml$ xmlsitemap.php [L]
# Any other requests for the form "/<anything>"
RewriteRule ^([^/]*)$ content.php?seourl=$1 [L]

How to add an excluding rewrite (un-rewrite) condition for specific file types?

I have the following simple rewrite, which I am taking a slightly different approach to rewriting site content.
RewriteEngine On
RewriteRule ^(.*)$ controller.php?page=$1 [NC,L,QSA]
The goal, is to rewrite all files and folders, everywhere, except if the file is of a particular type.
Traditionally, the following approaches are taken which are bit too relaxed for this endeavor :
1. Exclude all files/folders that physically exist:
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
2. Exclude specific folders from rewrite
RewriteRule ^somepath - [L]
3. Rewrite only specific file types
RewriteRule ^\.html index.php [NC,L,QSA]
4. Combination of #2 and file types
RewriteCond %{REQUEST_URI} !/images/.*
RewriteRule ^(.*\.(gif|jpg|png))$ images/$1 [QSA,L]
What I am wondering is what rule do I insert to exclude (keeping the sample short): jpg,bmp,png from being rewritten to controller.php regardless of the subfolder they are located in.
Pseudocode
RewriteEngine On
# skip rewriting jpg,bmp,png
RewriteRule ^[..something here..] - [NC,L]
# rewrite everything else
RewriteRule ^(.*)$ controller.php?page=$1 [NC,L,QSA]
RewriteCond %{REQUEST_FILENAME} !.*\.extensiongoeshere

.htaccess rewrite blank spaces with - ("%20" to "-")

I want to remove %20 on my link to - (dash),
My .htaccess is like that right now,
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ icerik.php?name=$1 [QSA,L]
For example,
site.com/vision-and-mision,
site.com/do-re-mi-fa-so-la-si.
Actually I searched something but the informations were very specific and I'm confused
Thank you.
You can use the following in your /.htaccess file:
RewriteEngine On
# Replace whitespace with hyphens, set the environment variable,
# and restart the rewriting process. This essentially loops
# until all whitespace has been converted.
RewriteRule ^([^\s]*)\s(.*)$ $1-$2 [E=whitespace:yes,N]
# Then, once that is done, check if the whitespace variable has
# been set and, if so, redirect to the new URI. This process ensures
# that the URI is rewritten in a loop *internally* so as to avoid
# multiple browser redirects.
RewriteCond %{ENV:whitespace} yes
RewriteRule (.*) /$1 [R=302,L]
Then add your rules afterwards:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /icerik.php?name=$1 [QSA,L]
If this is working for you, and you would like to make the redirects cached by browsers and search engines, change 302 to 301.

Resources