Remove php extension and parameters using Mod Rewrite in .htaccess to create two seo friendly urls - apache

I have read ALOT of threads about htaccess rewriting but struggling to get anything to work as I need it to.
I am spinning my wheels here for a few hours.
I have two pages in my folder.
/proposal/index.php
/proposal/dl.php
So normal queries would look like this.
/proposal/?code=123abc
/proposal/dl.php?code=123abc.
But I want to send it to the user like this:
/proposal/123abc/
/proposal/dl/123abc/
Can someone help me with this?
TIA
NOTE
I did try the code below which works perfectly on index.php but has no effect on dl.php (if I add dl.php to the mix)
RewriteEngine On
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule . index.php [L]

This probably is the variant you are looking for. Both rules capture the actual argument embedded in the requested URL to re-use it in the internally rewritten request.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [END]
RewriteRule ^dl/([^/]+)/?$ dl.php?code=$1 [END]
RewriteRule ^([^/]+)/?$ index.php?code=$1 [END]
Yo may also want to add redirection rules to redirect clients using the "old" URLs:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [END]
RewriteCOnd %{QUERY_STRING} ^code=([^/]+)$
RewriteRule ^dl\.php$ dl/%1 [R=301,END]
RewriteRule ^index\.php$ %1 [R=301,END]
RewriteRule ^$ /%1 [R=301,END]
RewriteRule ^dl/([^/]+)/?$ dl.php?code=$1 [END]
RewriteRule ^([^/]+)/?$ index.php?code=$1 [END]
For this it is a good idea to start out with a 302 redirection and only to change it to 301 when everything works as expected.
Both variants use relative paths so that the rules work in distributed configuration files somewhere deeper than the document root of your http server. I personally prefer to implement such rules in the real host configuration instead of using distributed configuration files ("htaccess") for various reasons.

In the end, this worked.
RewriteEngine On
RewriteRule ^dl/(.*) dl.php/$1 [L]
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule . index.php [L]
Now I am able to call the pages like this:
/proposal/123abc/
/proposal/dl/123abc/
All I did was add the line below to my original code.
RewriteRule ^dl/(.*) dl.php/$1 [L]
The structure of my subdirectory is as follows:
/proposal/.htaccess
/proposal/index.php
/proposal/dl.php
Now I am able to provide nice URLs to the clients for these two files and call up their content using my parameter like:
/proposal/123abc
/proposal/dl/123abc
Which would be like this in a normal way
/proposal/index.php?code=123abc or /proposal/?code=123abc
/proposal/dl.php?code=123abc

Related

shorten url with htaccess

I have an old system and would like to shorten the URL.
At the moment:
www.site.com/app/views/accessories.php
I would like to open it like this:
www.site.com/accessories.php
I tried to do like this:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteRule ^(.*)$ app/Views/$1 [NC,QSA]
But this error appears "Internal Server Error". What is wrong?
My folder structure is as follows:
As you can see the files are not in the root. They are inside two app/views/ folders.
Because of that the pages are opening with big and ugly links.
www.site.com/app/views/acessorios.php
www.site.com/app/views/clientes.php
www.site.com/app/views/empresas.php
I wish I could open them like this:
www.site.com/acessorios.php OR www.site.com/acessorios
www.site.com/clientes.php OR www.site.com/clientes
www.site.com/empresas.php OR www.site.com/empresas
That is, without looking like app/views/ in the url.
1st solution: With your shown samples and attempts please try following .htaccess rules file. Make sure to place your .htaccess rules file along with your app folder(not inside it, along side it). Also make sure to clear your browser cache before testing your URLs.
RewriteEngine ON
RewriteBase /app/views/
##External redirect rules from here.
RewriteCond %{THE_REQUEST} \s/app/views/([^.]*\.php)\s [NC]
RewriteRule ^ /%1? [R=301,L]
##Internal rewrite rules from here.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^.]*\.php)/?$ /app/views/$1 [QSA,L]
2nd solution: Rules to redirect URLs to www.site.com/acessorios are as follows:
RewriteEngine ON
RewriteBase /app/views/
##External redirect rules from here.
RewriteCond %{THE_REQUEST} \s/app/views/([^.]*)\.php\s [NC]
RewriteRule ^ /%1? [R=301,L]
##Internal rewrite rules from here.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^([^/]*)/?$ /app/views/$1.php [QSA,L]

RewriteRules in htaccess for clean URL resolution and redirect from full URL to clean URL

I'm working on a website project, www.experimonkey.com. In the root directory, I have directories for experiments, games, etc., that I've been serving dynamically with php. I want to clean up the URLs so that instead of /experiments?eid=homemade-lava-lamp, for example, a user can go to /experiments/homemade-lava-lamp. I'd also like to have a redirect so that if a user goes to the old link, /experiments?eid=homemade-lava-lamp, they will be redirected to the clean link.
I thought I had figured out the first part of the problem with the following code in /experiments/.htaccess:
RewriteEngine On
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]
This works for the dynamic pages; however, I later realized that this would screw up the other, real directories in the /experiments folder. For example, the address /experiments/submit (which is actually /experiments/submit/index.php) redirects to /experiments/submit?eid=submit--why, I have no idea.
But also, no matter what combinations of the following code I tried (and all of the other threads and documentation I've read), I could not get the old URL to redirect to the clean URL:
RewriteCond %{QUERY_STRING} eid=(.+)
RewriteRule .+ https://www.experimonkey.com/experiments/%1 [R=301]
RewriteEngine On
Edit (almost working)
I've worked it out this far. Everything is now mostly working, except the last two parts create an infinite loop and I'm not sure how to fix it.
#Ignore existing directories and files unless has query string
RewriteCond %{QUERY_STRING} !eid=(.*)
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#Redirect and remove query string
RewriteCond %{QUERY_STRING} /?eid=(.*)
RewriteRule (.*) https://www.experimonkey.com/experiments/%1? [R=301,L]
#Rewrite internally to actual URL
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]
I finally figured it out--I hope this can help someone somewhere along the way (I honestly can't believe how long this took me to figure out).
#Ignore existing directories and files unless has query string
RewriteCond %{QUERY_STRING} !eid=(.*)
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -l
RewriteRule ^ - [L]
#Redirect and remove query string.
#First line was the crucial condition to stop loop by checking for internal redirect first.
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} /?eid=(.*)
RewriteRule (.*) https://www.experimonkey.com/experiments/%1? [R=301,L]
#Rewrite internally to actual URL
RewriteRule ^([a-zA-Z0-9\-]+)/?$ index.php?eid=$1 [L]

Using RewriteRule to write URL from page/unique_id to page.php?id=unique_id

I am trying to format my URL from http://jacqueskoekemoer.co.za/article/5 to http://jacqueskoekemoer.co.za/article?i=5 where i would be the article ID in the database.
Currently this URL works. But this one does not. It does change the url to article.php but it doesn't add the query string to the end.
I know this because it does not appear in print_r($_REQUEST); or print_r($_GET);
What am I doing wrong in my .htaccess file, or can you suggest other resources that I could look at to resolve the problem?
I have used the following 2 URL's primarily to get the RewriteRule working.
URL 1
URL 2
In .htaccess file the rule rewrite section looks like this:
RewriteEngine on
RewriteRule ^article/$ article.php?i=$1 [L] # Handle requests for "article"
#RewriteRule ^article/$/ article.php?i=$1 [NC,L] # Handle requests for "article"
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
Use the following rule:
RewriteEngine on
RewriteRule ^article/(\d+)$ article.php?i=$1 [L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php [L]

mod_rewrite redirect url if no file found to main page

I want to be able to Access my scripts without the .php, .html etc., so I already wrote
RewriteEngine on
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.php -f
RewriteRule ^(.*)$ $1.php
##same for other extensions
in my .htaccess file (note: this file lies not in the root-path), but I also want to Redirect every incorrect request to my main page, so that www.mysite.com/dir/incorrect will be rewritten to www.mysite.com/dir/.
But my first try (RewriteRule ^ / [R] after RewriteCond) redirected me to www.mysite.com/, my experiments with RewriteBase (RewriteBase . and RewriteBase /) didnt work and I also noticed that many similar scriptredirect to www.mysite.com/dir/index.php (www.mysite.com/dir/index in my case), but I really want to Redirect to www.mysite.com/dir/. Is there any way to achieve this?
Have it this way:
RewriteEngine on
# see if .php is found
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}\.php -f
RewriteRule ^(.*)$ $1.php [L]
# determine DIR_BASE dynamically
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=DIR_BASE:%1]
# if not found redirect to %{ENV:DIR_BASE}
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^ %{ENV:DIR_BASE} [L,R]

Simulating a 2-level If-Else using RewriteCond

I'm trying to get my head around RewriteCond, and want to rewrite any requests either to a static html page (if it exists), or to a specific index.php (so long as the requested file doesn't exist).
To illustrate the logic:
if HTTP_HOST is '(www\.)?mydomain.com'
if file exists: "/default/static/{REQUEST_URI}.html", then
rewrite .* to /default/static/{REQUEST_URI}.html
else if file exists: {REQUEST_FILENAME}, then
do not rewrite
else
rewrite .* to /default/index.php
I don't seem to have much trouble doing it when I don't need to test for the HTTP_HOST. Ultimately, this one .htaccess file will be handling requests for several domains.
I know I could get around this with vhosts, but I'd like to figure out how to do it this way.
I'm not too familiar with some of the other flags, will any of them be of use here (like chain|C, next|N or skip|S)?
Thanks in advance!
UPDATE: I've managed to do it, but would appreciate alternatives:
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{DOCUMENT_ROOT}/%1/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%1/static/$1.html [NC,L]
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..* [NC]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%1/index.php [L,QSA]
UPDATE #2: With help from Gumbo's answer, came up with another. I like that this would would require less maintenance in the case of added domains. (Thanks Gumbo!)
Are there any reasons why I shouldn't set ENV variables?
RewriteCond %{HTTP_HOST} ^(domainA|domainB)\..*$ [NC]
RewriteRule ^ - [E=APP:%1]
RewriteCond %{DOCUMENT_ROOT}/%{ENV:APP}/static/%{REQUEST_URI}.html -f
RewriteRule (.*)? /%{ENV:APP}/static/$1.html [NC,L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule .* /%{ENV:APP}/index.php [L,QSA]
I would probably do it like this:
RewriteCond %{HTTP_HOST} !^(www\.)?example\.com$
RewriteRule ^ - [S=2]
RewriteCond %{DOCUMENT_ROOT}/default/static%{REQUEST_URI}.html -f
RewriteRule !^default/static/ default/static%{REQUEST_URI}.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !^default/static/ default/index.php [L]
This is similar to your updated example. Except that the first rule will skip the following two rules if the host is not appropriate. And the RewriteRule patterns exclude any path that starts with /default/static/. But your rules are already pretty good.