Unwanted result while using .htaccess for 2 rules - apache

I'm working on a web application with PHP.
I'd like to have clean URLs, so I wrote a .htaccess file for it. Everything is ok, but just for 1 rule.
Look at the code below:
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Rule No.1
RewriteRule ^(.*)/(.*)/(.*)/?$ index.php?page=$1&id=$2 [NC,N]
# Rule No.2
RewriteRule ^(.*)/?$ index.php?page=$1 [NC,L]
This is my .htaccess file contents.
If I remove the Rule No.1, and the page be something like www.site.com/news, everything works fine. But when I want to navigate to page www.site.com/news/1/sample-text, all CSS, JavaScript, and image files will destroy (I have not access to them anymore).
Although I wrote Rule No.2 in .htaccess file, but anything did not work and the problem is steel alive.
All images, css and javascript paths are similar to ./js/jquery.js format.
Also, I put RewriteBase / in .htaccess file. But ... :(
Please help me.

Rules will be better if they are like this:
# Rule No.1
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)/(.*)/?$ index.php?page=$1&id=$2 [L]
# Rule No.2
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ index.php?page=$1 [L]
=> You need to repeat the RewriteCond lines here: they apply only to the RewriteRule which follows.
Notes:
NC flag (case insensitivity) is useless here
the first rule doesn't use $3
([^/]+) would make more sense than (.*)

Related

take variable from middle of url and append it to the very end

I have links like this
http://panel.domain.com/users/index.php?user=8
http://panel.domain.com/users/settings/index.php?user=8
I want to rewrite them into this:
http://panel.domain.com/users/8/
http://panel.domain.com/users/8/settings
I want it to take anything after the user id and put it after users, and then go to index.php of that page and put the userid at the end, like this: users/USERID/chain/of/directories/index.php?user=USERID
I can make the first rewrite with this:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?user=$1
I've tried doing something like this
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^users/(.*)/$ $2/index.php?user=$1
$2 is first, because it should be everything AFTER users/ID/, and then $1 should be /ID/, which gets placed at the end of the directory chain: users/ID/settings/index.php?user=ID
But I really just can't figure out how it works. I don't know what it is that makes $1 and $2 work, and I don't understand regex. I've been looking through the Pearl docs all night and just trying to slap stuff together but I just don't get it.
You may use this .htaccess code in site root .htaccess:
Options -MultiViews
RewriteEngine On
RewriteRule ^users/([\w-]+)(/.+)?/?$ /users$2/index.php?user=$1 [L,QSA]
This assumes you don't have any .htaccess inside /users/ directory.
Could you please try following, written and tested based on your shown samples. You could catch both the variables in a single shot itself, you need not to use 2 conditions for this one.
Place this .htaccess file inside your users folder only.
Please make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteBase /users/
RewriteRule ^/?$ index.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\d+)/?$ index.php?users=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(\d+)/.*$ settings/index.php?users=$1 [L]

Adding exceptions to mod_rewrite

I got my basic redirects work with the mod_rewrite module. When requesting pages e.g. localhost/home it's correctly redirecting to localhost/index.php?page=home, but I have a problem with exceptions.
I created a folder api where I store files by category e.g. api/auth/register.php and api/customer/create.php. I tried to make rewrite rule that contains 2 params (in this example auth and customer) so basically it just drops the .php off from the url.
The rule that I made is following
RewriteRule ^api/(.*)/(.*)/?$ api/$1/$2.php [L]
After adding that line to my .htaccess, problems started to occur. For example my .css and .js files started to redirect. So maybe I need to make some exeption for the apis? Have you some other ideas to improve my rewrite rules?
.htaccess
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/(.*)/(.*)/?$ api/$1/$2.php [L] # problems started to occur after adding this line
RewriteRule (.*) index.php?page=$1 [L,QSA]
Thanks in advance.
RewriteCond will affect only the first following RewriteRule so you need the keep them next to your initial Rule, and move the added one above them (with its own conditions).
Also, your /api rule is not strict enough ((.*) will pick anything, including the slashes), which might not matter in you case, but still. I sugest you try with this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^api/([^/]*)/([^/]*)/?$ api/$1/$2.php [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.php?page=$1 [L,QSA]

.htaccess RewriteRule not working, bad flag delimiters

My site previously uses URL's like this: /folder/page
Previously, you could prepend 'panel' in the URL to edit the current page: /panel/folder/page
We upgraded our CMS, and the new URL to edit the page is in this format: /panel/#/pages/show/folder/page
I am trying to add a rewrite rule so that we can still use the old way, but can't get it to work:
RewriteCond %{REQUEST_URI} !^/panel/#/
RewriteRule /panel(.*) /panel/#/pages/show/$1
Is there a way to do this? A 301 redirect should work too, I think.
Edit: here is my existing .htaccess:
RewriteEngine on
RewriteBase /
# make panel links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^panel/(.*) panel/index.php [L]
# make site links work
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*) index.php [L]
Since "panel" is already used, I ended up using this redirect rule:
RedirectMatch 301 /admin(.*) /panel/#/pages/show/$1

RewriteRule not working fine

I wrote the following rule in .htaccess
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^(.*)/$ profile.php?business=$1
When i enter the URL like
http://www.abc.com/mujeeb/
page is correctly transfered to profiles page and page looks fine.
But i enter this in URL
http://www.abc.com/mujeeb
page doesn't show.
Can you please tell why? Or write the rule for this? i tried many times but not sucessful.
Mujeeb.
page doesn't show. because you specified that you RewriteRule is applied to the URL's ending with / at the end. Rewrite it as
RewriteRule ^(.*)/?$ profile.php?business=$1 [L]
And I hope that you have additional RewriteCond statements in order to prevent the infinite loop with redirects.
ps: basically you can prevent loop in two way
1) checks that requested url does not correspond to the existing file or directory. it is, probably, the best way to do (read comments to the second method)
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/?$ profile.php?business=$1 [L]
2) checks that you are requesting not the file from RewriteRule. This method is not good, because for each request, even for existing files and directories, it calls profile.php script
RewriteCond %{REQUEST_URI} !profile\.php$
RewriteRule ^(.*)/?$ profile.php?business=$1 [L]
It is because you check for the trailing slash with ^(.*)/$. If you add a question mark, the trailing slash will be optional.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteRule ^(.*)/?$ profile.php?business=$1
The RewriteCond is neccessary to make sure the Rule will only be applied once. Otherwise Apache will be caught in an infinite loop.
Try this:
Options +FollowSymLinks
RewriteEngine on
RewriteRule ^(.*)[/]?$ profile.php?business=$1
That makes the last slash optional.
Well you rule is checking for a trailing slash in URI and that's the reason /mujeeb/ works but /mujeeb does not. Change your code to:
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
# If the request is not for a valid file
#RewriteCond %{REQUEST_FILENAME} !-d
# If the request is not for a valid directory
#RewriteCond %{REQUEST_FILENAME} !-f
# your rule without trailing slash
RewriteRule ^(.*)$ profile.php?business=$1 [L,QSA]
Plenty of good answers already. My answer is a bit different.
This is what I usually do. If the requested URL doesn't end with a /, I make the browser redirect to a URL with the trailing /. This is consistent with the default behaviour of Apache (due to mod_dir). So, this is how I solve this problem.
RewriteEngine On
# Canonicalize http://example.com/mujeeb to http://example.com/mujeeb/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)([^/])$ /$1$2/ [R=307,L]
# Let profile.php process http://example.com/mujeeb/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ profile.php?business=$1

problems working with 'rewrite' in apache2

I have the following list of URLs to rewrite:
1 write url
/products/client/
send to
/basedir/system/index.php?client=cliente
2 write url
/product/client/index.php
send to
/basedir/system/index.php?client=cliente
3 write url
/products/client/image/dir2/myimage.jpg
send to
/basedir/system/image/client/dir2/myimage.jpg
4 write url
/products/client/image/dir2/more_x_dir/other.img
send to
/basedir/system/image/client/dir2/more_x_dir/other.img
With these rules I have more or less solved the points 1 and 2:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^product/([a-zA-Z]+)$ /basedir/system/index.php?client=base=$1 [L,QSA]
RewriteRule ^product/([a-zA-Z]+)/$ /basedir/system/index.php?client=base=$1 [L,QSA]
RewriteRule ^product/([a-zA-Z]+)/(.*)$ /basedir/system/index.php?client=$1 [L,QSA]
My problem is in cases 3 and 4 when I have files with css / image's / js. and also when I have many directories, it may be that in the case of many directories have to make a rule for everyone, but I do not know how.
thank you very much
Edit
my solution based on the answer accepted:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^product/([a-zA-Z]+)/(.*)\.(gif|jpg|ico|css|js|txt|zip|xls|doc)$ /basedir/system/$2.$3 [L,QSA]
RewriteRule ^product/([a-zA-Z]+)$ /basedir/system/index.php?database=$1 [L,QSA]
RewriteRule ^product/([a-zA-Z]+)/$ /basedir/system/index.php?database=$1 [L,QSA]
RewriteRule ^product/([a-zA-Z]+)/index.php$ /basedir/system/index.php?database=$1 [L,QSA]
RewriteRule ^product/([a-zA-Z]+)/(.*)$ /basedir/system/$2?database=$1 [L,QSA]
I believe that you want to do something like the following, based on your description (I'm still a little confused about the rules that you currently have). I also make the assumption that you had folders named image, css, and js for each client.
RewriteEngine On
# Rewrite images/css/js to their real files
RewriteRule ^products/([^/]+)/(image|css|js)/(.*)$ /basedir/system/$2/$1/$3 [L]
# Rewrite everything else to the index.php script
RewriteRule ^products/([^/]+)(/.+)?$ /basedir/system/index.php?client=$1 [QSA,L]