Clean URL redirection htaccess - php

i have a website SongsBar.com , when a query is searched on my website, the url in the browser displays like this - http://songsbar.com/download.php?q={search text}.
i want it be appear like this http://songsbar.com/download/{search text}.html

.htaccess
RewriteEngine On
RewriteRule ^download/([^/]*)\.html$ /download.php?q=$1 [L]

First, you need to make sure Multiviews (mod_negotiation) is turned off, otherwise it'll mess with the /download/ and /download.php stuff.
Then you need to externally redirect requests for download.php
Then you need to internally rewrite the /download/ requests back to the php file (the browser is oblivious to this happening.
Options -Multiviews
RewriteEngine On
RewriteCond %{THE_REQUEST} \ /+download.php\?q=([^&\ ]+)
RewriteRule ^ /download/%1.html? [L,R=301,NE]
RewriteRule ^download/(.+)\.html$ /download.php?q=$1 [L,B,QSA]
The B flag may not be necessary. It depends on what kind of stuff you plan on putting in the parameter. The flag ensures that special characters get encoded.

http://httpd.apache.org/docs/current/mod/mod_rewrite.html
Something like : RewriteCond %{REQUEST_FILENAME}

You can achieve this with something along the lines of:
RewriteEngine On
RewriteBase /download/
RewriteCond %{REQUEST_FILENAME} !-f #if the file actually exists don't rewrite
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)\.html$ /download.php?q=$1 [L]

Related

.htaccess rewrite url with letters öäå and passing variables

Lets say survey name is test.
When completing form it redirects to
www.example.com/survey_thank_you.php?survey_name=test
then rewrites it to www.example.com/test/thank_you and it works as inteded.
But because here we use öäå the issue emerge. If survey name is testä, it redirects allright but rewrites it to
www.example.com/test%25C3%25A4/thank_you (this works)
and it should rewrite to www.example.com/testä/thank_you
also if go straight to www.example.com/testä/thank_you it works.
htaccess:
Options +FollowSymLinks
Options -MultiViews
RewriteEngine on
AddCharset UTF-8 .php
AddDefaultCharset utf-8
RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^survey_name=(.*)/?$
RewriteRule ^survey_thank_you\.php$ /%1/thank_you [R,L,QSD]
RewriteRule ^(.*)/thank_you$ survey_thank_you.php?survey_name=$1 [L,NC,QSA]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
RewriteRule ^(.*)/?$ survey_form.php?survey_name=$1 [L,NC,QSA]
If i change (.*) to ([0-9a-zA-Z]+) it rewrites it allright /testä/thank_you but then i get error 404. Any suggestions much appreciated.
test%25C3%25A4 would be the result of double URL encoding. One level decoded, leaves test%C3%A4.
You can use the NE flag to try and avoid double encoding in this place, https://httpd.apache.org/docs/2.4/rewrite/flags.html#flag_ne

URL mod_rewrite how to properly create syntax?

I have the following url:
http://example.com/files/101-info/index.php
My questions is:
Is it possible to remove the 101- in the url?
Is it possible to rewrite the name in the address bar, but keep the file in the current location?
I would like to make the file appear to be at:
http://example.com/files/info/index.php
but actually remain in:
/var/www/htdocs/files/101-info/index.php
Here's what I tried, but I couldn't remove the 101- and the redirect didn't work:
RewriteEngine On
RewriteRule ^([^/]+)/([0-9]+)-([^\/]+)/(.+)\.php$ /$1/$2/$4 [R] // also tried [NC,QSA]
NOTE: Keep in mind if you have other rules in your .htaccess that you have not mentioned in your question and you don't place the below rules at the proper place, it will not work as expected.
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteBase /
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+files/[0-9]+-([^/]+)/([^\s\?]+) [NC]
RewriteRule ^ /files/%1/%2 [R=302,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(files)/([^/]+)/([^/]+)$ /$1/101-$2/$3 [L]
First rule will remove the 101-, the 2nd rule will accept the 101- internally without having to change the folder name or the place your files are.
Change it from [R=302,L] to [R=301,L] once you confirm it is working.
Since you were previously using a redirect, your browser might be cached, so clear you cache and make sure to test the URL with a different browser until the cache of yours is cleared as it doesn't always happen after deleting it.

mod_rewrite and hyperlinks with spaces

So I'm no .htaccess expert, by no means, but I have managed to put this code together for a webiste I'm making:
Options -Indexes +Includes
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteBase /
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteRule ^\.htaccess$ - [F]
RewriteRule ^$ /%{ENV:BASE}/index.php?id=home
RewriteCond %{REQUEST_URI} !\.php$ [NC]
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ $1 [R=301,L]
RewriteRule ^([a-zA-Z0-9]*)$ /%{ENV:BASE}/index.php?id=$1 [QSA,L]
</IfModule>
It basically changes www.example.com/some/dir/index.php?id=home to www.example.com/some/dir/home while the first few rules are creating some kind of relative path value so I don't have to change the RewriteBase everytime I change the base folder (this is important for this project!).
It works perfectly fine, but now I have encountered a problem where there have to be spaces in the URL like www.example.com/some dir/sub folder/home and this messes everything up.
If you click a link on the page (e.g. "href="home"") it redirects to www.example.com/home instead of www.example.com/some dir/sub folder/home with a 404 error, obviously (even though it works if there are no spaces!). I found out if right click > "copy link to clipboard" it becomes the encoded version www.example.com/some%20dir/sub%20folder/home even if it shows the decoded version in the address bar. BUT if you manually type the decoded version www.example.com/some dir/sub folder/home it still works fine.
There seems to be a problem with spaces and encoding. How do I get my hyperlinks working properly?
-- EDIT --
Thanks to the tutorial posted by elcodedocle, I simply added backslash space: ^([a-zA-Z0-9/ ]*)$ to the regex in the last rule, even if it's not the best method. Then I noticed the [L] flag in the second last rule. I removed it because this shouldn't be the last rule (don't know why it was there in the first place...) and now it works! Well, kind of...
Now, If there is a trailing slash at the end of the URL it sill doesn't work anymore. Probabply because of the removal of the [L] flag in the rule but I don't know how to fix this...
Have your .htaccess like this:
Options -Indexes +Includes -MultiViews
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI}::$1 ^(.*?/)(.*)::\2$
RewriteRule ^(.*)$ - [E=BASE:%1]
RewriteCond %{REQUEST_URI} !\.php$ [NC]
RewriteCond %{REQUEST_FILENAME} !-s
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)/$ %{ENV:BASE}$1 [R=302,L,NE]
RewriteRule ^\.htaccess$ - [F]
RewriteRule ^$ /%{ENV:BASE}/index.php?id=home [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+?)/?$ %{ENV:BASE}index.php?id=$1 [QSA,L]
</IfModule>
This is working fine under all the test cases you have described in your question like handling spaces, trailing slashes etc.
Try changing:
RewriteRule ^([a-zA-Z0-9]*)$ /%{ENV:BASE}/index.php?id=$1 [QSA,L]
to
RewriteRule ^([a-zA-Z0-9%]*)$ /%{ENV:BASE}/index.php?id=$1 [QSA,L]
(It's a wild guess but it's the only one of your rules that has problems with %)
[EDIT] Unencoded spaces are not allowed in URIs. The ban on spaces is enforced by all browsers as they will convert every space to %20 before sending the request via the http protocol. A workaround to handle them in mod_rewrite is described on this tutorial:
Since URLs can't have spaces (except as %20), use underlines or
hyphens to replace them. If you ABSOLUTELY have to use spaces (%20) in
your URIs, you can include them in your regex within a range
definition as {space}, i.e., ([a-zA-Z\ ]+). However, this is NOT
advised.
[EDIT2] If that doesn't work, you may have to translate %20 into spaces, then apply the other rules. Here is a hack based on this answer you may try:
sedspace.sh:
#!/bin/sh
sed -u 's/%20/ /g'
.htaccess:
...
RewriteMap sed-space prg:sedspace.sh
RewriteRule ^(.*)$ ${sed-space:$1}
...
(Make sure that sedspace.sh is executable)

Clean URL with htaccess. no query string variable received

I am working on urls of a site. I want to convert the following url into
http://dev.steelogic.com/solution.php?id=metalbuildingproduct
this url
http://dev.steelogic.com/solution/metalbuildingproduct
this is the htaccess code I am using.
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.+)/(.+)$ $1.php?id=$2
I don't know anything about htaccess. usually I just copy paste the text and it works.
the url with ?id= works fine
but when try to use the 2nd url it doesn't have any id.
I have to do this to many other pages as well and the all contain [.php?id=] which I want to replace with [/] slash
Try this rule in your DocumentRoot/.htaccess:
Options +FollowSymLinks -MultiViews
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([^/]+)/([^/]+)/?$ /$1.php?id=$2 [L,QSA]
Please try this:
<IfModule mod_rewrite.c>
Options +SymLinksIfOwnerMatch
RewriteBase /
RewriteRule ^solution/([^/.]+)/?$ solution.php?id=$1 [PT,L,NC,QSA]
</IfModule>
Because you say that even without this rule, going to http://example.com/solution/asdf loads /solution.php on your server, something else must be working on your url. Because you say you didn't define such a rule, it must be coming from somewhere else. Either a rule is defined somewhere else (main config file) or MultiViews is enabled. If you can't apply anubhava's solution (disabling MultiViews), move your file somewhere else, for example under /public/solution.php, so that url never partly matches an existing file, then use the following rule.
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{DOCUMENT_ROOT}/public/$1.php -f #partly copied from anubhava's answer
RewriteRule ^([^/]+)/([^/]+)/?$ /public/$1.php?id=$2 [L]
from all of the discussion I concluded that its difficult enough to do it with .htaccess as there might b some sort of module working on the urls of site from the hosting and I get both solution and solution.php directed to same page
so I did it in php for now.
as both of the following pages
http://dev.steelogic.com/solution.php?id=metalbuildingproduct
and
http://dev.steelogic.com/solution/metalbuildingproduct
being going to same pages but with the second url I was not getting query string var. so I wrote a PHP code as I knew on each page how many vars I need so it worked for me. although it may not be a good approach but it works
$URI = explode("/", trim($_SERVER['REQUEST_URI']));
$numElems = count($URI);
if ($numElems <= 4) {
$arr = array();
$arr['id'] = $URI[2];
if (!empty($URI[3]))
$arr['id2'] = $URI[3];
}
if any body can help me with .htaccess I will appreciate.

.htaccess not allowing sub-directory to work

Here is the .htaccess file
RewriteEngine on
RewriteCond $1 !^(index\.html|index.php|administrator|system|template|js|lib|favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ /index.html?tpl=$1 [L]
Options +FollowSymlinks
However what is happening is that all the following folders wont allow me to go into them and view a PHP file.
|administrator|system|template|js|lib
I thought by putting the files in RewriteCond that it would allow a user to still go to http://example.com/news/happy which then would go to the index.php?tpl=etc etc but it has stopped me from going into any subdirectory like
http://example.com/system/index.php
I don't know if this would work for you. But what I do is to add this rules to load calls to any .php file without the .php ending. You can call both, with or without that ending.
For example, you can call my_url.com/myfolder/myfile and it will load myfile.php, with the friendly URL.
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}\.php -f
RewriteRule ^(.*)$ $1.php
i would like to recommend that you read about mod rewrite first
1 - put that line at top
Options +FollowSymlinks
That line ask your server to follow symlinks but i would like recommend that you use the more secure option "SymLinksIfOwnerMatch"
Source:
http://httpd.apache.org/docs/2.2/mod/core.html#options#FollowSymLinks
RewriteEngine on
Enables or disables runtime rewriting engin
Source:
http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html#rewriteengine
RewriteCond $1 !^(index\.html|index.php|administrator|system|template|js|lib|favicon\.ico|robots\.txt)
Here you go . that rule ask the web server to add rewrite Condition to ignore everything listed in your regex
also i have added regex explain for you
!
not equal
^
Start with
RewriteRule ^(.*)$ /index.html?tpl=$1 [L]
you are asking to write everything else to index.html?tpl=$1
** I think you mean index.php i will assume that you don't need the query string
i would like to recommend using a better way to handle the excluding
RewriteEngine On
Options +FollowSymLinks
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !(index\.html|index.php|administrator|system|template|js|lib|favicon\.ico|robots\.txt)
RewriteRule ^(.*)$ /index.html?tpl=$1 [L]

Categories