url rewrite using htaccess without redirection - php

I have a url like this:
http://www.localhost.com/code_category/computers/
I want to change this url to:
http://www.localhost.com/category/computers/
I don't need url redirection.
My current htaccess file looks like this:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>

You only want to redirect code_category to categoryexternally and keep the path as it is internally so, try this :
RewriteCond %{THE_REQUEST} !\s/+category/ [NC]
RewriteRule ^code_category/(.*)$ category/$1 [R=302,L,NE]
RewriteRule ^category/(.*)$ code_category/$1 [L]
The above will redirect any request containscode_category/whatever to category/whatever externally and keep the internal path as it is .
If you want only request contains code_category/computers/ change it to this :
RewriteCond %{THE_REQUEST} !\s/+category/computers/ [NC]
RewriteRule ^code_category/computers/(.*)$ category/computers/$1 [R=302,L,NE]
RewriteRule ^category/computers/(.*)$ code_category/computers/$1 [L]
test it , if it is fine change 302 to 301 for permanent redirection.
Note: clear your browser cache then test it.

.htaccess file
Add this code
RewriteEngine on
RewriteCond %{HTTP_HOST} ^localhost.com [NC,OR]
# without redirect
# RewriteRule ^/code_category/computers/$ category/computers/
RewriteRule ^/category/computers/$ code_category/computers/
# redirect method
# RedirectMatch 301 ^/code_category/computers/$ category/computers/
RewriteEngine On enables mod_rewrite.
RewriteCond %{HTTP_HOST} shows which URLs we do and don't want to run through the rewrite.
In this case, we want to match example.com.
! means "not." We don't want to rewrite a URL that already includes folder1, because then it would keep getting folder1 added, and it would become an infinitely long URL.
[NC] matches both upper- and lower-case versions of the URL.
RewriteRule defines a particular rule.
The first string of characters after RewriteRule defines what the original URL looks like. There's a more detailed explanation of the special characters at the end of this article.
The second string after RewriteRule defines the new URL. This is in relation to the document root (html) directory. / means the html directory itself, and subfolders can also be specified.
For Reference click here
Hope this helps!

Related

Mod_rewrite multi domain names

So I have 2 domain names on one server 2 different sites I have mod-rewrite on the one domain name which I would like to work for the one domain name only but when I upload the .htaccess file the 1 domain name works great but the other site / domain name shows
Not Found
The requested URL was not found on this server.
Additionally, a 404 Not Found _error_ was encountered while trying to use an ErrorDocument to handle the request.
If I remove the mod rewrite file the second site works and shows but the first site needs the mod rewrite to work
is there any way to set the mod rewrite to only run for the one domain name?
Just wanted to add the main domain name is in the root and the second domain name is in a file in the root so I want all the conditions to work for domain name 1 which is in the root but not domain name 2 which is in a folder in the root. When I visit domain name 2 I get a 404 error.
options -multiviews
options All -Indexes
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} mydomainname.com$ [NC]
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteRule ^home$ index.php
RewriteRule ^dashboard$ dashboard.php
RewriteRule ^advertiser$ advertiser.php
RewriteRule ^add_campaign$ add_campaign.php
RewriteRule ^edit_campaign$ edit_campaign.php
RewriteRule ^stats$ view_statistics.php
RewriteRule ^login$ login.php
RewriteRule ^logout$ logout.php
RewriteRule ^withdrawals$ withdrawals.php
RewriteRule ^register$ register.php
RewriteRule ^report$ report.php
RewriteRule ^referrals$ referrals.php
RewriteRule ^contact$ contact.php
RewriteRule ^add_wallet$ add_wallet.php
RewriteRule ^payment_page$ payment_page.php
RewriteRule ^forgot_password$ forgot_password.php
RewriteRule ^my_account$ my_account.php
RewriteRule ^(admin)($|/) - [L]
RewriteRule ^([A-Za-z0-9-]+)/?$ view_link.php?s=$1 [L]
RewriteRule ^page_([^/]+)/?$ pages.php?slug=$1 [L]
</IfModule>
RewriteConds work only on the one RewriteRule immediately following them, so you would have to repeat them before every single one.
It might make more sense to work with a negated pattern here - check if the host name was not mydomainname.com, and follow that by a rule that simply says, “okay we done here”, by using the [L] flag.
RewriteEngine On
RewriteBase /
# check if the host name was not mydomainname.com
# pattern anchored at the start using ^ as well here, so that notmydomainname.com
# would not be matched as well, and the . escaped
# whole thing negated, by putting ! in front of it
RewriteCond %{HTTP_HOST} !^mydomainname\.com$ [NC]
# match absolutely anything with the .
# don’t do any actual rewriting, by using - as the substitution
# [L] flag to say, that’s it, we are done with the rewriting here
RewriteRule . - [L]
# … rest of your rules follow here
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f
# …

htaccess doesn't work as expected

I have an htaccess rewrite URL as below:
RewriteEngine On
RewriteCond %{HTTP_HOST} ^www.mywebsite.com$ [NC]
RewriteRule ^(.*)$ http://mywebsite.com/$1 [R=301,L]
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^my-page\.html$ /my-page.php [L]
RewriteRule ^my-page/([^/]*)\.html$ /level1.php?num=$1 [L]
RewriteRule ^my-page/([^/]*)/([^/]*)\.html$ /level2.php?level1=$1&level2=$2 [L]
RewriteRule ^([^/]*)\.html$ /level3.php?level3=$1 [L]
These rules above rewrite URLs from mywebsite.com/my-page.php to mywebsite.com/my-page.html.
Now, what I want to achieve is mywebsite.com/my-page/ to be redirected to mywebsite.com/my-page.php (which in turn rewrites to mywebsite.com/my-page.html).
What I have tried, I created a directory "my-page" and tried to redirect requests from mywebsite.com/my-page/ to /my-page.html.
I don't know what went wrong. I can see in the network tab that a request is made to /my-page/ and gets rewritten to mywebsite.com/my-page.htmlmy-page/, which gives a 302 Status ☹
Please help! Thank you.
You can try use RedirectMatch to achieve this.
Redirect to my-page.php:
RedirectMatch 301 ^/my-page/ http://mywebsite.com/my-page.php
or straight away to my-page.html if this is your goal:
RedirectMatch 301 ^/my-page/ http://mywebsite.com/my-page.html
or, what will be best - change the code responsible for mywebsite.com/my-page.htmlmy-page/, but I can't see it in question you have asked :)
Please give the following a try. Brief descriptions are found in the comments for each section.
RewriteEngine On
# Trim www.
RewriteCond %{HTTP_HOST} ^www\.mywebsite\.com$ [NC]
RewriteRule ^(.*)$ http://mywebsite.com/$1 [R=301,L]
RewriteBase /
# Redirect /my-page[/] to /my-page.html
# >> Note: change 302 to 301 to make permanent
RewriteRule ^my-page/?$ my-page.html [R=302,L]
# Allow existing files and directories
# Recommended to comment out the first line
RewriteCond %{REQUEST_FILENAME} -d
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
# Rewrite *.html to respective page
RewriteRule ^my-page.html$ my-page.php [L]
RewriteRule ^my-page/([^/]*).html$ level1.php?num=$1 [L]
RewriteRule ^my-page/([^/]*)/([^/]*).html$ level2.php?level1=$1&level2=$2 [L]
RewriteRule ^([^/]*).html$ level3.php?level3=$1 [L]
The important part here is that you do the required redirect before any other rewrites (except the www. removal).
Also, you previously had the two conditions which stated that if the request was not for a file or directory, then proceed with the next rule, but that wouldn't have accounted for the last two rules. As such, this version tells Apache to stop everything if the request is for an existing file or directory. I would recommend, for security purposes, that you comment out the line that checks for existing directories.

htaccess add .html extension for urls with or without trailing slash

So to begin with I have a custom url rewrite that sends a request variable to a php script
Rewrite rule is below:
RewriteRule ^([\w\/-]+)(\?.*)?$ test/index.php?slug=$1 [L,T=application/x-httpd-php]
So if you access something like domain.com/slug-text it sends slug-text to index.php located in folder named test.
What I want is all my urls to look like domain.com/slug-text.html, but slug-test variable should still be sent to index.php file.
And
What I can't figure out is the redirect. I want all the old urls to be redirected from domain.com/slug-text or domain.com/slug-text/ to domain.com/slug-text.html and slug-text sent to index.php file located in test folder.
Searched a lot but could not find the answer for this question anywhere on the Internet.
Thank you all for the help.
UPDATE:
my new code is:
RewriteEngine On
Options +FollowSymlinks
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-l
RewriteRule ^(([\w/\-]+)?[\w-])(?!:\.html)$ http://domain.com/$1\.html [L,R=301]
RewriteRule ^(([\w/\-]+)?[\w-])(/|\.html)?$ test/index.php?slug=$1 [L]
domain.com/slug-text/ does not get redirected to domain.com/slug-text.html
domain.com/slug-text works as intended redirecting to domain.com/slug-text.html
What do i need to change?
This rule:
RewriteRule ^(([\w/\-]+)?[\w-])(/|\.html)?$ test/index.php?slug=$1 [L]
Will trap domain.com/slug-text, domain.com/slug-text/ and domain.com/slug-text.html and send slug-text to /test/index.php inside slug param.
If you really want to redirect using [R=301] from old urls to new then use this:
RewriteRule ^(([\w/-]+)?[\w-])/?(?!:\.html)$ http://domain.com/$1.html [L,R=301]
RewriteRule ^(([\w/-]+)?[\w-])\.html$ test/index.php?slug=$1 [L]
Also note that as using explicit redirect bottom rule is modified to trap url's ending with .html
It is also advisable (if your .htaccess does not already contain this) to filter conditions for existing files and folders not to be trapped by your redirect rules. Simply add these lines before RewriteRule lines:
# existing file
RewriteCond %{SCRIPT_FILENAME} !-f
# existing folder
RewriteCond %{SCRIPT_FILENAME} !-d
And if using symlinks:
# enable symlinks
Options +FollowSymLinks
# existing symlink
RewriteCond %{SCRIPT_FILENAME} !-l
// addition
Your .htaccess file should look like this:
RewriteEngine on
Options +FollowSymLinks
RewriteCond %{SCRIPT_FILENAME} !-f
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-l
RewriteRule ^(([\w/-]+)?[\w-])/?(?!:\.html)$ http://domain.com/$1.html [L,R=301]
RewriteRule ^(([\w/-]+)?[\w-])\.html$ test/index.php?slug=$1 [L]
This is supposed to redirect /slug-text to /slug-text.html
RedirectMatch ^/([\w-]+)/?$ http://domein.com/$1.html
This is in the case when slug-text is only letters, digits, – and _.
Rewrite slug-text.html to a php file and pass the slug as a param:
RewriteRule ^([\w-]+)\.html$ test/index.php?slug=$1 [R,L]
If you have both line in your .htaccess the first one will do the redirects from the legacy URLs to the new ones and the second one will process the request.

Issue with mod_rewrite when accessing directory

My code:
RewriteEngine on
RewriteBase /
RewriteRule ^article/([a-z]+)/?$ index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ index.php?page=$1 [L]
I am using WAMP and had setup a Virtual Host.
In my index.php, there is code to get page passed and checks if it exists(in database). If not, display an error message. It works fine.
Eg: http://mysite/contactus/
But it will not work if I use a a directory name as page_name in the URL. Eg: http://mysite/images/. This will display page not found error (ie. checks database and no page found, so display "not found"). But it will not display images,css(linked file) in the page. Also, it shows http://mysite/images/?page=images in addressbar.
Like that, if I goto js folder which is used to store javascript files, above problem occurs. So, problem is caused if any subdirectory's name is passed as pagename.
How to solve this ?
When http://mysite/images/ is supplied, mod_rewrite is redirecting to http://mysite/images/index.php?page=images instead of http://mysite/index.php?page=images
Edit
Please tell me how to block hotlinking of files and directory, and redirect back to index page or send some browser header error ?
I tried this:
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*) http://%{HTTP_HOST} [R,L]
RewriteRule ^article/([a-z]+)/?$ /index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ /index.php?page=$1 [L]
Edit
New code(semi-working):
RewriteEngine on
RewriteBase /
# remove trailing slash ONLY if it is not an existing folder
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ /$1/ [R,L]
RewriteRule ^article/([a-z]+)/?$ http://%{HTTP_HOST}/index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ http://%{HTTP_HOST}/index.php?page=$1 [L]
This code will clear the problem with not displaying pics and css when a directory name is mentioned. But whatever pagename i specify eg:http://mysite/contactus, it will goto URL: http://mysite/index.php?page=contactus. Even if I use a directory name eg: http://mysite/js, it will goto: http://mysite/index.php?page=js
I am very confused.
RewriteEngine on
RewriteBase /
RewriteRule ^article/([a-z]+)/?$ index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/*$ /index.php?page=$1 [L]
you have to put the slash in front.
Edit: changed the ? to *
My understanding is that your script is for documents only, not images or other resources.
Then you should ignore them right away. Try adding this line right after RewriteBase like this :
RewriteEngine on
RewriteBase /rewrite/
RewriteRule ^/(images|js)/(.*)$ - [L]
RewriteRule ^article/([a-z]+)/?$ index.php?page=article&name=$1 [L]
RewriteRule ^([a-z]+)/?$ index.php?page=$1 [L]
Then these subdirectories would be served right away, thus bypassing the next RewriteRule set.
For the problem with the directories I usually force a slash
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^\.]+[^/])$ $1/ [R]

mod_rewrite to remove .php but still serve the .php file?

I just wanted to do a simple thing with mod_rewrite. I have a site which uses .php files, and I wanted to rewrite those to cleaner URLs, and remove the .php. So, files would be www.mysite.com/contact and so on.
This does work how I wanted, but I had expected that it would still serve my contact.php file, but just show the user that they were at /contact rather than contact.php. But, it is looking for a file just called contact, which, is not there.
So, what so I need to do, do still use my contact.php file, but rewrite the URL for the user to /contact ?
Here is what I am using:
SetEnv APPLICATION_ENV development
RewriteEngine on
RewriteBase /
# Always use www.
RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301]
# Change urlpath.php to urlpath
RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
RewriteRule ^(.*)\.php$ http://www.mysite.com/$1 [L,R=301]
For this solution, I have followed the following rules:
If the user tries to load /something.php they should be externally redirected to /something.
If the user tries to load /something then they should be internally redirected to /something.php.
If the user passed any query string parameters to the URL then these should be preserved through the redirects.
If the user tries to load a different file which really exists on the filesystem (a stylesheet, image etc) then this should be loaded as is.
And here's the final set of mod_rewrite magic:
RewriteEngine on
RewriteBase /
## Always use www.
RewriteCond %{HTTP_HOST} ^mysite\.com$ [NC]
RewriteRule ^(.*)$ http://www.mysite.com/$1 [L,R=301]
# Change urlpath.php to urlpath
## Only perform this rule if we're on the expected domain
RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
## Don't perform this rule if we've already been redirected internally
RewriteCond %{QUERY_STRING} !internal=1 [NC]
## Redirect the user externally to the non PHP URL
RewriteRule ^(.*)\.php$ $1 [L,R=301]
# if the user requests /something we need to serve the php version if it exists
## Only perform this rule if we're on the expected domain
RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
## Perform this rule only if a file with this name does not exist
RewriteCond %{REQUEST_FILENAME} !-f
## Perform this rule if the requested file doesn't end with '.php'
RewriteCond %{REQUEST_FILENAME} !\.php$ [NC]
## Only perform this rule if we're not requesting the index page
RewriteCond %{REQUEST_URI} !^/$
## Finally, rewrite the URL internally, passing through the user's query string
## using the [qsa] flag along with an 'internal=1' identifier so that our first
## RewriteRule knows we've already redirected once.
RewriteRule ^(.*)$ $1.php?internal=1 [L, QSA]
Your third rule should be the other way around:
# Change urlpath.php to urlpath
RewriteCond %{HTTP_HOST} ^www\.mysite\.com$ [NC]
RewriteCond %{REQUEST_FILENAME} !\.php$ [NC]
RewriteRule ^/?(.*)$ $1.php [L,R=301]
Once the user goes to /contact, it'll load contact.php. The extra RewriteCond is so that if people DO go to contact.php, it won't try to load contact.php.php
As I understand you want the URL to be /contact even if the URL was /contact.php.
You can check for the .php extension and do a redirect to remove it. Use R=301 (as you do).
Then you have to make your server accept the URL without the .php extension. It might actually already do that.
That's what mod_negotiation does. It should be installed by default, but you might have to enable it.
You can also do that with mod_rewrite, but remove the R from the options. It will redirect internally instead of answering with an HTTP redirect.

Categories