.htaccess and mod_rewrite - can't get it to work - php

I'm trying to use names as the url, like stackoverflow. I have a godaddy linux hosting and am using .htaccess to control the mod_rewrite url.
I'm trying to get the following:
/about => about.php
/schools/add => add-school.php
/api/questions/ask => /questions.php?action=ask
/api/questions/158 => /questions.php?action=get&id=158
/api/questions/144/points => /questions.php?action=get-points&id=144
This is what I have so far and it's not working:
## Mod rewrite manual: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
<IfModule mod_rewrite.c>
RewriteEngine On
# try the corresponding php file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([A-Za-z0-9_-]+) $1.php [qsa]
# special cases
RewriteRule ^schools\/add$ add-school.php
# API
RewriteRule ^api\/questions\/ask$ "api.php?action=ask" [qsa]
RewriteRule ^api\/questions\/(\d+)$ "api.php?action=get&id=$1" [qsa]
RewriteRule ^api\/questions\/(\d+)\/points$ "api.php?action=get-points&id=$1" [qsa]
</IfModule>

There are few mistakes in your code:
Rewrite rules ordering is very important. You should always order from most specific ones to most generic ones. Remember generic ones can match patterns of specific rules and override those special cases.
Always mark individual end of rule with L (last).
Forwarding requests to .php you need to make sure that php file actually exists.
With those suggestion here is your modified code:
Options +FollowSymLinks -MultiViews
<IfModule mod_rewrite.c>
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# special cases
RewriteRule ^schools/add/?$ /add-school.php [L,NC]
# API
RewriteRule ^api/questions/ask/?$ /api.php?action=ask [L,QSA,NC]
RewriteRule ^api/questions/(d+)/points/?$ /api.php?action=get-points&id=$1 [L,QSA,NC]
RewriteRule ^api/questions/(d+)/?$ /api.php?action=get&id=$1 [L,QSA,NC]
# try the corresponding php file if it exists
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^(.+?)/?$ $1.php [L]
</IfModule>

So your first RewriteRule is taking over. When you go to schools/add and the file doesn't exist it redirects you to schools.php which also doesn't exist so you just need to reorder them and while we're at it remove the escaping:
## Mod rewrite manual: http://httpd.apache.org/docs/2.0/mod/mod_rewrite.html
<IfModule mod_rewrite.c>
RewriteEngine On
# special cases
RewriteRule ^schools/add$ add-school.php
# API
RewriteRule ^api/questions/ask$ api.php?action=ask [qsa]
RewriteRule ^api/questions/(d+)$ api.php?action=get&id=$1 [qsa]
RewriteRule ^api/questions/(d+)/points$ api.php?action=get-points&id=$1 [qsa]
# try the corresponding php file
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ([A-Za-z0-9_-]+) $1.php [qsa]
</IfModule>

Related

Using htaccess with Codeigniter and specific rules

I can not add specific rewrite rule to .htaccess file in which codeigniter rewrite rules present.
Options -Indexes
Options +FollowSymLinks
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI}
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond $1 !^(index\.php|images|robots\.txt|css|docs|js|system|sayfalar|main\.php)
RewriteRule ^(.*)$ /index.php?/$1 [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^main/(.*)$ /main.php?tag=$1 [L,NC]
DirectoryIndex home.php
</IfModule>
The section RewriteRule ^main/(.*)$ /main.php?tag=$1 [L,NC] not working at all
When I type site.com/main/decoraion corresponding to main.php?tag=decoration , I got Codeigniter'S 404 error page. Codeigniter's rule handles the request though I tell htaccess not to consider main.php file when rewriting
What is the correct way for adding this rule?
You should swap the two rules :
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule .* https://%{HTTP_HOST}%{REQUEST_URI}
# => Put your specific rule here !
RewriteRule ^main/(.*)$ /main.php?tag=$1 [L,NC]
# The remaining route, acting as a "catch-all"
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# I'm not really sure the purpose of your next condition, but I suspect it's useless. See comment.
#RewriteCond $1 !^(index\.php|images|robots\.txt|css|docs|js|system|sayfalar|main\.php)
RewriteRule ^(.*)$ /index.php?/$1 [L]
DirectoryIndex home.php
</IfModule>
Just to remind you, [L] means that this rule should be the last one to apply if it matches.
So when you did RewriteRule ^(.*)$ /index.php?/$1 [L], you told Apache to match any URL and rewrite it to your index, and to not look for further rules. Hence your issue.
So the main takeaway is to rewrite to index at the end (to act like a "catch-all"), and add specific route before.

Friendly Url don't get the link [duplicate]

I am just new to .htaccess.
I need some rewrite rules for URLs.
I Google'd some and applied but no change in URL.
I want:
demo.example.com/section.php?id=1
Changed to:
demo.example.com/section/sample-section
i tried
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^section/(\d+)*$ ./section.php?id=$1
but no difference
Thanks.
I will appreciate your help.
First, make sure mod_rewrite is enabled and htaccess files allowed in your Apache configuration.
Then, put this code in your htaccess (which has to be in root folder)
Options -MultiViews
RewriteEngine On
# redirect "/section.php?id=xxx" to "/section/xxx"
RewriteCond %{THE_REQUEST} \s/section\.php\?id=([0-9]+)\s [NC]
RewriteRule ^ /section/%1? [R=301,L]
# internally rewrite "/section/xxx" to "/section.php?id=xxx"
RewriteRule ^section/([0-9]+)$ /section.php?id=$1 [L]
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^section/([^/]+)$ /section.php?id=$1 [L]
This will turn example.com/section.php?id=X to example.com/section/X
I suggest storing the URI in a database then using section.php?uri=
For example:
example.com/section.php?uri=super-awesome
would turn into:
example.com/section/super-awesome

htaccess removes the GET variables

I am editing a script and need to read GET variables to make my job done. But it seems the .htaccess file is manipulating it and removes everything at the end of custom URLs. I have no idea how to modify apache configurations to make it to works fine for the script yet me.
Options +FollowSymLinks
RewriteEngine on
RewriteBase /
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/(.*)$ index.php?route=$1/$2 [L]
</IfModule>
<IfModule mod_rewrite.c>
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?route=$1 [L]
</IfModule>
Here is a sample of URL I need to call:
http://domain.tld/controller/plugin/function/route?k1=v1&k2=v2
and the $_GET only contains one 'route' key with the value below:
controller/plugin/function/route
And other query strings are missed. What should I do for having them?
You probably want the QSA: Query String Append rewrite flag which does what it says on the tin.
For example:
RewriteRule ^(.*)/(.*)$ index.php?route=$1/$2 [L,QSA]

htaccess - Need help writing the correct rule

I'm using SimpleMVCFramework
All my routes are working fine, based on the default htaccess file:
Options -Indexes
<IfModule mod_rewrite.c>
Options -Indexes
RewriteEngine On
RewriteBase /mpl/servicos/smvcf/
# Force to exclude the trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.*)/$
RewriteRule ^(.+)/$ $1 [R=307,L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [QSA,L]
</IfModule>
I have a route that expects an id:
http://localhost/mpl/servicos/smvcf/detalhe/37343
But I need the URL the user sees to be friendly as:
http://localhost/mpl/servicos/smvcf/mercedes_benz-a-a_220_cdi_auto-37343.html
I thought something like this would work, but I get a 404:
RewriteRule ([^/]+)-([^/]+)-([^/]+)-([^/]+).html detalhe/$4
Please help.
The user sees the pretty url, but you are not interested in what the seo-title is. What you are interested in is the number that is hidden in it. As the number is in the very back of the pretty url, let's just match on that:
RewriteRule ^[^/]+-([0-9]+)\.html detalhe/$1 [L]
If you are trying to use another rewrite that will not be routed through the default MVC route index.php then you need to make sure you place your new rewrite before those rules. Also that folder you are redirecting to will need to have a index PHP file to do something as well.
Options -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /mpl/servicos/smvcf/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)-([0-9]+)\.html detalhe/$2 [L]
# Force to exclude the trailing slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} (.*)/$
RewriteRule ^(.+)/$ $1 [R=307,L]
# Allow any files or directories that exist to be displayed directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?$1 [QSA,L]
</IfModule>

How do I resolve the conflict of rules in this .htaccess file?

Each of the rules in the file works well if I comment out the other, but the two of them together do not achieve either purpose but rather renders the site ugly. Any suggestion on how to resolve this? Thanks.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} !-d
# If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} !-f
# If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} !-l
# do not do anything
RewriteRule ^ - [L]
# forward /blog/foo to blog.php/foo
RewriteRule ^blog/(.+)$ blog.php/$1 [L,NC]
# forward /john to user_page/profile.php?name=john
RewriteRule ^((?!blog/).+)$ user_page/profile.php?uid=$1 [L,QSA,NC]
Try replace RewriteRule ^((?!blog/).+)$ with RewriteRule ^(.+)$ there is no need to check for blog string again
I've finally figured this out. I modified the second rewrite condition because the second rewrite rule redirects to a url that is not necessary valid i.e www.example.com/username to the intended valid url which looks like this www.example.com/user_page/profile.php?user=username.
I also modified the last/second rewrite rule as Safarov suggested and it worked! Below is the full .htaccess file.
Options +FollowSymLinks -MultiViews
# Turn mod_rewrite on
RewriteEngine On
RewriteBase /
# If the request is for a valid directory
RewriteCond %{REQUEST_FILENAME} -d [OR]
# OR If the request is for a valid file
RewriteCond %{REQUEST_FILENAME} -f [OR]
# OR If the request is for a valid link
RewriteCond %{REQUEST_FILENAME} -l
# do not do anything
RewriteRule ^ - [L]
# forward /blog/foo to blog.php/foo
RewriteRule ^blog/(.+)$ blog.php/$1 [L,NC]
# forward /john to user_page/profile.php?name=john
RewriteRule ^(.+)$ user_page/profile.php?uid=$1 [L,QSA]

Categories