mod_rewrite to make clean URL with multiple patterns - php

I'm trying to make clean URLs for my application. So I wrote the codes below in a .htaccess file.
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)/?$ index.php?p=$1&id=$2 [NC,L]
RewriteRule ^(.*)/?$ index.php?p=$1 [NC,L]
As you can see, I may have at most 2 variable in query string; p and id. If I have just one rule (the rule with 1 variable) in .htaccess file, everything will be fine. But when I add the first rule (the rule with 2 variable), it seems that all css, js, and image files will be go away.
I wrote css, images, and js files in this way :
./directory_name/file_name
Please help me to make clean URLs with multiple rules.

If you're following a Front-Controller Pattern, (i.e. everything goes through index.php) I'd encourage you to use FallbackResource.
FallbackResource /index.php
It's more concise and performant than the mod_rewrite equivalent (as seen in anubhava's answer):

Change your code to:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
RewriteRule ^([^/]+)/([^/]+)/?$ /index.php?p=$1&id=$2 [QSA,L]
RewriteRule ^([^/]+)/?$ /index.php?p=$1 [QSA,L]

Related

rewrite rule for single or multiple folders

My htaccess code for URL rewrite:
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^compare/(.*)/?$ compare.php?page=$1 [L,QSA]
RewriteRule ^compare/(.*)/(.*)?$ compare.php?page=$1&location=$2 [L,QSA]
This rule works for :
www.example.com/compare/car
But it is not working for:
www.example.com/compare/car/india
I want to modify the rewrite rule which works for these urls:
www.example.com/compare/car
www.example.com/compare/car/india
Is it possible? How can I modify my rewrite rule to achieve this?
There are 2 problems with your code:
.* in first rule is too greedy which matches a / so first rule is also matching /compare/car/india as well as /compare/car
Since your URI is starting with /compare and rule is rewriting to compare.php you need to turn off content negotiation by turning off MultiViews.
Your last rule is without any RewriteCond as that is only applicable to next immediate RewriteRule directive.
You may use this code in your site root .htaccess:
Options -MultiViews
RewriteEngine On
RewriteBase /
# skip all files and directories from rewrite
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# one path element after compare
RewriteRule ^compare/([^/]+)/?$ compare.php?page=$1 [L,QSA,NC]
# two path elements after compare
RewriteRule ^compare/([^/]+)/([^/]+)/?$ compare.php?page=$1&location=$2 [L,QSA,NC]

PHP file not able to access $_GET variable after .htaccess rewrite rule

I have a number of PHP pages with query strings in the URLs on my site. I'm trying to change the URLs for SEO, to do this I'm using an .htaccess file.
I'm new to .htaccess so this is fairly basic and I'm not sure if I'm doing this right or if there is a better way to do it.
My .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_URI} !/.css$
RewriteCond %{REQUEST_URI} !/.js$
RewriteCond %{REQUEST_URI} !/.png$
RewriteCond %{REQUEST_URI} !/.jpg$
RewriteRule ^category/([0-9a-zA-Z]+) category.php?id=$1
RewriteRule ^product/([0-9a-zA-Z]+) product.php?id=$1
RewriteRule ^page/([0-9a-zA-Z]+) page.php?page_id=$1
This allows me to access the page category.php?id=1 at category/1 the same for the other pages I have rewrite rules for. However my php script can no longer access the $_GET variable from the URL so it is rewriting correctly but now unable to show any of the content?
You will need to turn MultiViews option off and also do little bit refactoring of your rules.
Options -MultiViews
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^category/([0-9a-zA-Z]+)/?$ category.php?id=$1 [L,NC,QSA]
RewriteRule ^product/([0-9a-zA-Z]+)/?$ product.php?id=$1 [L,NC,QSA]
RewriteRule ^page/([0-9a-zA-Z]+)/?$ page.php?page_id=$1 [L,NC,QSA]
Option MultiViews (see http://httpd.apache.org/docs/2.4/content-negotiation.html) is used by Apache's content negotiation module that runs before mod_rewrite and makes Apache server match extensions of files. So if /file is the URL then Apache will serve /file.html.

.htaccess ignoring flags, not matching next rule

I am building simple php mvc application, but have problem with .htaccess, it looks like it is ignoring flags and doesn't want to run next line
Options -MultiViews
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteRule ^(en|sk)(\/)(.+)$ index.php?url=$3&lang=$1 [C]
RewriteRule ^(.+)$ index.php?url=$1 [C]
my goal is to have multilingual site with adresses like http://example.com/lang/something, I used this as mvc skeleton link to github repo but it misbehaves
when going to http://127.0.0.10, everything ok
when going to http://127.0.0.10/en/home page also works
when going to http://127.0.0.10/home page not works
then when I removed first rule or swapped rules order, going to http://127.0.0.10/home started to work, but when going to http://127.0.0.10/en/home not, I undestand in first case here error was in place because app thinks "en" is controller, but what in second case ?
Rewrite condition is applicable for only immediate next RewriteRule hence 2nd RewriteRule is without any conditions.
Try this code:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
RewriteRule ^(en|sk)/(.+)$ index.php?url=$2&lang=$1 [L,QSA]
RewriteRule ^(.+)$ index.php?url=$1 [L,QSA]

HTAccess Url rewriting rules

I'm trying to simply the access to my API with a .htaccess file and I'm facing an issue.
For example, what I'd like to achieve is:
User reaches http://localhost/teammngr/user/photos/secrethash and is automatically redirected to http://localhost/teammngr/user/photos.php?sid=secrethash.
User reaches http://localhost/teammngr/user/config/secrethash and is automatically redirected to http://localhost/teammngr/user/config.php?sid=secrethash.
User reaches http://localhost/teammngr/team/members/secrethash and is automatically redirected to http://localhost/teammngr/team/members.php?sid=secrethash.
If the user wants to reach these files directly, it is supposed to be possible.
Moreover, the url http://localhost/teammngr/ will be under a subdomain like http://team.mywebsite.com/.
So far, I've made the following .htaccess file, but it keeps throwing a 500 error on my server.
To be clear, this file is not in the root directory but in a sub dir.
Options +FollowSymlinks
RewriteEngine On
RewriteBase /teammngr
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^user/([a-z_]+)/([A-Za-z0-9_-]+)$ /user/$1.php?sid=$2 [L]
RewriteRule ^team/([a-z_]+)/([A-Za-z0-9_-]+)$ /team/$1.php?sid=$2 [L]
Where did I make a mistake ?
Thanks for your precious help.
RewriteCond is only applicable to very next RewriteRule. To avoid repeated RewriteCond before every rule you can have a separate rule to ignore requests for files and directories. Also remove / from your target URIs.
Options +FollowSymlinks -MultiViews
RewriteEngine On
RewriteBase /teammngr/
# ignore requests for files and directories from rules below
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^user/(\w+)/([\w-]+)/?$ user/$1.php?sid=$2 [L,QSA]
RewriteRule ^team/(\w+)/([\w-]+)/?$ team/$1.php?sid=$2 [L,QSA]
you can try this:
Options +FollowSymlinks
RewriteEngine On
RewriteBase /teammngr
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^user/([a-z_]+)/([A-Za-z0-9_-]+)$ user/$1.php?sid=$2 [L]
RewriteRule ^team/([a-z_]+)/([A-Za-z0-9_-]+)$ team/$1.php?sid=$2 [L]

.htaccess - Redirect subfolder to index.php using subfolder name as variable

This is driving me mad. I'm trying to use .htaccess to redirect a subfolder (that doesn't exist) to the index page, using the subfolder name as the variable. ie:
http://www.website.com/john/
redirects to:
http://www.website.com/index.php?name=john
I've tried this (and various others) with no luck:
Options +FollowSymLinks
RewriteEngine On
RewriteRule ^(.*)$ index.php?name=$1
Here is an example, how you can do this:
# turn mod_rewrite engine on
RewriteEngine On
# rewrite a physical existing file or folder
RewriteCond %{REQUEST_FILENAME} !-f [OR]
RewriteCond %{REQUEST_FILENAME} !-d
# allow things that are certainly necessary
RewriteCond %{REQUEST_URI} "/layout/" [OR]
RewriteCond %{REQUEST_URI} "/javascript/"
# rewrite rules
RewriteRule .* - [L]
RewriteRule (.*) index.php?_route=$1 [QSA]
This one also denies access to folders you don't want to have public.
Try this one:
RewriteRule ^([^/]*)/$ /?name=$1 [L]
RewriteRule ^([^.]*)$ /index.php?name=$1 [L,QSA]

Categories