mod_rewrite with name replacing ID - php

I have a page on my website that dynamically displays content. The URL structure is mywebsite.com/giveaway/giveaway.php?id=(any number)
I wish to change that dynamic URL into a static/friendly URL mywebsite.com/giveaway/name-of-giveaway-corresponding-to-id.
In my .htaccess file found in my root folder i have the following:
RewriteEngine On
# external redirect from actual URL to pretty one
RewriteCond %{THE_REQUEST} \s/+\?page=([^\s&]+) [NC]
RewriteRule ^ /page/%1? [R=301,L]
# existing rule
RewriteRule ^page/([^/]+)/?$ /?page=$1 [L,QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^([^\.]+)$ $1.php [L]
The current .htaccess file removes .php and also redirects and changes a URL on my site from
mywebsite.com?page=number to mywebsite.com/page/number
I know you have to get the name corresponding to the ID in php from my database and use that, but im not sure how to write the code in the .htaccess file or how to use and pass the results from the database. Thanks for any help!

I don't know if that is what you mean, but you can't connect the rewrite engine, which is part of the underlying Apache server layer, to the database, which has to be accessed by php.
So you can't rewrite the "name-of-giveaway-corresponding-to-id" to the id directly, you need to rewrite it to something like giveaway.php?nameofgiveaway=(name of giveaway) and then search the database for that string.
Your way to go is to add a rewrite rule like
RewriteRule ^giveaway/([^/]+)$ giveaway.php?nameofgiveaway=$1 [L,QSA]
(not tested, so forgive me if something is wrong) and search for $_GET['nameofgiveaway'].

Related

How do i use .htaccess to clean a url generated by php

I have following URLs:
http://www.example.com/item?title=titlename&id=5 and
http://www.example.com/page?title=titlename
I want to convert them like:
http://www.example.com/item/titlename/5
http://www.example.com/page/titlename
Note: the page and item are files (ie: item.php and page.php), I was able to remove the .php extension using the following code:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s([^.]+)\.php [NC]
RewriteRule ^ %1 [R=301,L]
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME}.php -f
RewriteRule ^(.*?)/?$ $1.php [NC,L]
Any little help would be appreciated.
i just want to internally rewrite the url from something like http://www.example.com/item?title=titlename&id=5 and http://www.example.com/page?title=titlename to something like this: http://www.example.com/item/titlename/5 or http://www.example.com/page/titlename.
That should be the other way round... internally rewrite from http://www.example.com/item/titlename/5 to http://www.example.com/item?title=titlename&id=5. And presumably you should be including the .php extension on the target URL? (Don't rely on another directive to do append the file extension.)
Try something like the following:
Options -MultiViews
RewriteEngine On
RewriteRule ^([a-z]+)/([\w-]+)(?:/(\d+))?$ /$1.php?title=$2&id=$3 [L]
This will handle a URL both with and without the trailing ID (eg. /5). However, if you specify a URL of the form /item/titlename (ie. no numeric id), then you will naturally get an empty id URL parameter passed to your script.
Note that MultiViews must be disabled for this to work, otherwise mod_negotiation will rewrite the URL from item to item.php (for example) before mod_rewrite and you won't get the URL parameters passed.
If you specifically need to check that the target file, eg. page.php exists before rewriting then you can include an additional condition to check this. However, I wouldn't have thought this was necessary since you'll get a 404 regardless and checking that the file exists is relatively expensive.
Options -MultiViews
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}/$1.php -f
RewriteRule ^([a-z]+)/([\w-]+)(?:/(\d+))?$ /$1.php?title=$2&id=$3 [L]
This assumes that your files exist in the document root of your site.
Just to clarify, as mentioned in comments, you should already be linking to URLs of the form http://www.example.com/item/titlename/5 in your application.

"Smart" rewrite rule for basic web app

I'm trying to create a regexp for my .htaccess with high amount of flexibility, I know my solution is not the best, but this is what I want for the specific project.
So.
/website is my base and .htaccess currently look like:
RewriteRule ^([A-Za-z0-9-]+)/$ index.php?page=$1&$2 [NC,L]
This works fine aslong as I am visiting /website/anypagename pages. What I want to do next is ?to=allow&getquery=strings and fetch them with $_GET in php, but the .htaccess won't let me.
I also want my .htaccess to allow ANY /-urls where the structure would look like:
/website/pagename/z1/x1/z2/x2/z3/x3
where z1 is a name of a $_GET variable, and x1 is its value. Of course normal get arguments shall work aswell.
However I tweak it I can't get it to do what I want. Also, with the z1/x1 structure - will I be able to visit physical files or even load css?
Try this code:
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^ - [L]
RewriteRule "^([^/]+)/([^/]+)/([^/]+)(/.*)?$" /$1$4?$2=$3 [L,QSA]
RewriteRule ^([^/]+)/?$ /index.php?page=$1 [QSA,L]

htaccess Redirect Causes Errors

I'm working on a website that has been built sloppily.
The website is filled with regular links that are translated into the corresponding .php pages by the .htaccess page.
This is it:
RewriteEngine on
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
First of all, I would love some help regarding whether or not this page has everything it should. I've never messed with it before.
Secondly and my main issue, if, for example, I would write the address www.thewebsite.com/foobar.html, it would be translated into www.thewebsite.com/cat.php?cat=foobar by the .htaccess page, and it would give a database error (and reveal information about the database).
I've put a check into cat.php which checks if the category exists, but I can't redirect the user to the 404 error page. There's a page called 404.shtml in the website, but redirecting the user to it causes the .htaccess to just change it again to cat.php?cat=404.
Is the way they used the .htaccess page normal? Should I change this system?
And how are users sent to error pages? From what I understood the server should be doing it on its own?
I would love some clarification... There is some much about this subject I don't understand.
Update:
This is my new .htaccess page
RewriteEngine on
RewriteRule ^error.php?err=(.*)$ Error$1.html
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^koral/(.*)/$ page.php?name=$1
RewriteRule ^koral/(.*)$ page.php?name=$1
RewriteRule ^(.*).html/(.*)/(.*)/(.*)$ cat.php?cat=$1&page=$2&order=$3&dir=$4
RewriteRule ^(.*).html$ cat.php?cat=$1
RewriteRule ^(.*)/(.*).html$ product.php?cat=$1&product=$2
<IfModule mod_security.c>
SecFilterEngine Off
</IfModule>
Because the redirecting is in the code and the user cannot see it, I allowed myself to write the link in a non-clean way. I tried turning it into a clean URL but the following does not do anything:
RewriteRule ^error.php?err=(.*)$ Error$1.html
Can someone please help me understand why? I thought since error.php is a real page, I should put it before the conditional but it didn't work. BTW, I saw in an article about .htaccess that the page should start with Options +FollowSymLinks. It seems to me that everyone sort of has their own way of writing it. Is there a guide or something like that, which I can be sure is authentic and covers all the bases there is about .htaccess?
Thank you so much!!
Using rewrite rules to work around links to .html pages that don't exist is unusual in my experience, but it's really just a different take on "pretty" URLs, e.g. www.thewebsite.com/foobar/ gets routed to cat.php?cat=foobar on the backend.
Your 404 issue is different. You need to be able to display error pages.
One option here is to rewrite requests as long as they don't request an existing file. This is very common for serving up static content like images, CSS files, and the like. To do this, you can use the -d and -f options to RewriteCond, which apply when requesting a directory and file respectively:
RewriteEngine On
# Only apply this rule if we're not requesting a file...
RewriteCond %{REQUEST_FILENAME} !-f [NC]
# ...and if we're not requesting a directory.
RewriteCond %{REQUEST_FILENAME} !-d [NC]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
Now, requests to 404.shtml should go through, because you're requesting an existing file on the filesystem.
Note that the RewriteConds only apply to the single RewriteRule that immediately follows. For additional RewriteRules, also include additional RewriteConds.
Your regex is wrong anywhere. Literal dot needs to be escaped using otherwise it will match any character. Also it is better to use L and QSA flags to end each rule properly.
RewriteEngine on
RewriteBase /
RewriteRule ^koral/([^/]+)/?$ page.php?name=$1 [L,QSA]
RewriteRule ^([^.]+)\.html/([^/]+)/([^/]+)/([^/]*)/?$ cat.php?cat=$1&page=$2&order=$3&dir=$4 [L,QSA]
RewriteRule ^([^.]+)\.html$ cat.php?cat=$1 [L,QSA]
RewriteRule ^([^/]+)/([^.]+)\.html$ product.php?cat=$1&product=$2 [L,QSA]

Rewrite url which redirects to page on webserver

I am trying to get a page with a query string to redirect to a nicer looking url then get that url and transfer it back to the original query string but without redirecting (i.e. without changing the url)
At the moment I am getting a redirect loop (for obvious reasons) but I was hoping for a way to stop this.
This is my code in my htaccess file
#rewrite search querystring
#/search/'apartment'/2_bedrooms/price_0-500000/town_W4/development_18,SW5/
RewriteRule ^search/([^/]+)/([^/]+)_bedrooms/price_([^/]+)-([^/]+)/town_([^/]+)/development_([^/]+) /search.php?propertytype=$1&bedrooms=$2&minprice=$3&maxprice=$4&location=$5&development=$6 [NC]
RewriteCond %{QUERY_STRING} propertytype=([^/]+)&bedrooms=([^/]+)&minprice=([^/]+)&maxprice=([^/]+)&location=([^/]+)&development=([^/]+)
/search/$1/$2_bedrooms/price_$3-$4/town_$5/development_$6 [R,L]
RewriteRule ^(.*)$ /search/%1/%2_bedrooms/price_%3-%4/town_%5/development_%6? [R,L]
So what it is meant to do is:
user has been taken to:
http://www.domain.com/search/?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
This page is the actual page on the server where the data is coming from, however I want the user to see.
http://www.domain.com/search/dev/2_bedrooms/price_0-10000000/town_W1/development_W1/
Is it possible to do this without a redirect loop.
Thanks for your help
EDIT I'm thinking it could be done with the rewrite flags but I'm not sure, I'm quite new to the Rewrite Engine
Edited:
Here is a complete (and working) solution for you:
RewriteEngine On
# User gets here:
# http://localhost/search/?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
# He is explicit redirected to here:
# http://localhost/search/dev/2_bedrooms/price_0-10000000/town_W1/development_W1/
# Internally, apache calls this:
# http://localhost/search.php?propertytype=dev&bedrooms=2&minprice=0&maxprice=10000000&location=W1&development=W1
RewriteRule ^search/([^/]+)/([^/]+)_bedrooms/price_([^/]+)-([^/]+)/town_([^/]+)/development_([^/]+) search.php?propertytype=$1&bedrooms=$2&minprice=$3&maxprice=$4&location=$5&development=$6 [NC,PT]
RewriteCond %{QUERY_STRING} propertytype=([^/]+)&bedrooms=([^/]+)&minprice=([^/]+)&maxprice=([^/]+)&location=([^/]+)&development=([^/]+)
RewriteRule ^search/(.*)$ /search/%1/%2_bedrooms/price_%3-%4/town_%5/development_%6/? [R,L]
It assumes you put .htaccess in server root and that there is a file search.php in root too.
Original:
I think you can use PT and QSA Rewrite Rule flags (http://httpd.apache.org/docs/current/rewrite/flags.html) in your first rule
Use PT for server-side redirection (it will not change the URL for the user/browser, but will for your server-side scripts)
Use QSA if you wanna carry the query while doing this redirection
You can redirect all requests that don't target an existing file to a specific php-script, for example:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php?url=$1 [PT,QSA]

Pretty URLs only partially working correctly

With a bit of help from people here at Stackoverflow I've managed to put together a .htaccess file that permits 'pretty URLs'. This is great if a user types the 'pretty URL' directly into the address bar as the conversion works exactly as I would like it to do, but if a user clicks a link within my site that generates a dynamic link, the 'ugly URL' remains and the conversion doesn't take place. Is there something I need to add to the .htaccess file to get this to work, or do I need to code up some PHP to force the conversion for links?
My .htaccess file is set-up as follows:
Options -Multiviews
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !^mysite\.com$
RewriteRule ^(.*) http://mysite.com/$1 [R=301,L]
RewriteRule ^episode/(0|[1-9]\d{0,2})$ /episode.php?episode=$1 [L,QSA]
(Converts http://mysite.com/episode.php?episode=31 to http://mysite.com/episode/31.)
Just append this rule in the end to force pretty URL in browser:
RewriteCond %{THE_REQUEST} ^[A-Z]{3,}\s/+episode\.php\?episode=(\d+) [NC]
RewriteRule ^ episode/%1? [R=302,L]
Once working change R=302 to R=301.

Categories