This is an historic archive of the Grow Collective web site as it was in 2008.
Jon Tan, Jon Gibbins and Alan Colville have gone on to found Analog.
'Hmmmm, I have this lovely photograph that I have just taken and published on my site, but I really wish I had a way to know what my visitors thought about it. What I need is a rating system, but where can I get one that doesn't use any databases and is simple and easy to install'...?
DAH DAH DAHHHHHHH... Gr0w to the rescue once again (cue Superman theme music).
This is a very simple piece of PHP code that will allow the inclusion of single or multiple Star Rating Systems on one page. It uses no database, but instead utilises small text files to store it's required information. The output is presented in hReview Microformat. It also allows for ip voting restriction if required, and the ability to set how many times a single ip may vote.
Update: This system has been used in our free slide show application, Scooch.
Here is an example of the script in action: Rater Example
Download rater.zip
Below is the entire script that makes up the PHP Star Rating System.
<?
// User settings
$rater_ip_voting_restriction = true; // restrict ip address voting (true or false)
$rater_ip_vote_qty=1; // how many times an ip address can vote
$rater_already_rated_msg="You have already rated this item. You were allowed ".$rater_ip_vote_qty." vote(s).";
$rater_not_selected_msg="You have not selected a rating value.";
$rater_thankyou_msg="Thankyou for voting.";
$rater_generic_text="this item"; // generic item text
$rater_end_of_line_char="n"; // may want to change for different operating systems
if(!isset($rater_id)) $rater_id=1;
if(!isset($rater_item_name)) $rater_item_name=$rater_generic_text;
// DO NOT MODIFY BELOW THIS LINE
$rater_filename='item_'.$rater_id.".rating";
$rater_rating=0;
$rater_stars="";
$rater_stars_txt="";
$rater_rating=0;
$rater_votes=0;
$rater_msg="";
// Rating action
if(isset($_REQUEST["rate".$rater_id])){
if(isset($_REQUEST["rating_".$rater_id])){
while(list($key,$val)=each($_REQUEST["rating_".$rater_id])){
$rater_rating=$val;
}
$rater_ip = getenv("REMOTE_ADDR");
$rater_file=fopen($rater_filename,"a+");
$rater_str="";
$rater_str = rtrim(fread($rater_file, 1024*8),$rater_end_of_line_char);
if($rater_str!=""){
if($rater_ip_voting_restriction){
$rater_data=explode($rater_end_of_line_char,$rater_str);
$rater_ip_vote_count=0;
foreach($rater_data as $d){
$rater_tmp=explode("|",$d);
$rater_oldip=str_replace($rater_end_of_line_char,"",$rater_tmp[1]);
if($rater_ip==$rater_oldip){
$rater_ip_vote_count++;
}
}
if($rater_ip_vote_count > ($rater_ip_vote_qty - 1)){
$rater_msg=$rater_already_rated_msg;
}else{
fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
$rater_msg=$rater_thankyou_msg;
}
}else{
fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
$rater_msg=$rater_thankyou_msg;
}
}else{
fwrite($rater_file,$rater_rating."|".$rater_ip.$rater_end_of_line_char);
$rater_msg=$rater_thankyou_msg;
}
fclose($rater_file);
}else{
$rater_msg=$rater_not_selected_msg;
}
}
// Get current rating
if(is_file($rater_filename)){
$rater_file=fopen($rater_filename,"r");
$rater_str="";
$rater_str = fread($rater_file, 1024*8);
if($rater_str!=""){
$rater_data=explode($rater_end_of_line_char,$rater_str);
$rater_votes=count($rater_data)-1;
$rater_sum=0;
foreach($rater_data as $d){
$d=explode("|",$d);
$rater_sum+=$d[0];
}
$rater_rating=number_format(($rater_sum/$rater_votes), 2, '.', '');
}
fclose($rater_file);
}else{
$rater_file=fopen($rater_filename,"w");
fclose($rater_file);
}
// Assign star image
if ($rater_rating <= 0 ){$rater_stars = "./img/00star.gif";$rater_stars_txt="Not Rated";}
if ($rater_rating >= 0.5){$rater_stars = "./img/05star.gif";$rater_stars_txt="0.5";}
if ($rater_rating >= 1 ){$rater_stars = "./img/1star.gif";$rater_stars_txt="1";}
if ($rater_rating >= 1.5){$rater_stars = "./img/15star.gif";$rater_stars_txt="1.5";}
if ($rater_rating >= 2 ){$rater_stars = "./img/2star.gif";$rater_stars_txt="2";}
if ($rater_rating >= 2.5){$rater_stars = "./img/25star.gif";$rater_stars_txt="2.5";}
if ($rater_rating >= 3 ){$rater_stars = "./img/3star.gif";$rater_stars_txt="3";}
if ($rater_rating >= 3.5){$rater_stars = "./img/35star.gif";$rater_stars_txt="3.5";}
if ($rater_rating >= 4 ){$rater_stars = "./img/4star.gif";$rater_stars_txt="4";}
if ($rater_rating >= 4.5){$rater_stars = "./img/45star.gif";$rater_stars_txt="4.5";}
if ($rater_rating >= 5 ){$rater_stars = "./img/5star.gif";$rater_stars_txt="5";}
// Output
echo '<div class="hreview">';
echo '<form method="post" action="'.$_SERVER["PHP_SELF"].'">';
echo '<h3 class="item">Rate <span class="fn">'.$rater_item_name.'</span></h3>';
echo '<div>';
echo '<span class="rating"><img src="'.$rater_stars.'?x='.uniqid((double)microtime()*1000000,1).'" alt="'.$rater_stars_txt.' stars" /> Ave. rating: '.$rater_stars_txt.'</span> from <span class="reviewcount"> '.$rater_votes.' votes</span>.';
echo '</div>';
echo '<div>';
echo '<label for="rate5_'.$rater_id.'"><input type="radio" value="5" name="rating_'.$rater_id.'[]" id="rate5_'.$rater_id.'" />Excellent</label>';
echo '<label for="rate4_'.$rater_id.'"><input type="radio" value="4" name="rating_'.$rater_id.'[]" id="rate4_'.$rater_id.'" />Very Good</label>';
echo '<label for="rate3_'.$rater_id.'"><input type="radio" value="3" name="rating_'.$rater_id.'[]" id="rate3_'.$rater_id.'" />Good</label>';
echo '<label for="rate2_'.$rater_id.'"><input type="radio" value="2" name="rating_'.$rater_id.'[]" id="rate2_'.$rater_id.'" />Fair</label>';
echo '<label for="rate1_'.$rater_id.'"><input type="radio" value="1" name="rating_'.$rater_id.'[]" id="rate1_'.$rater_id.'" />Poor</label>';
echo '<input type="hidden" name="rs_id" value="'.$rater_id.'" />';
echo '<input type="submit" name="rate'.$rater_id.'" value="Rate" />';
echo '</div>';
if($rater_msg!="") echo "<div>".$rater_msg."</div>";
echo '</form>';
echo '</div>';
?>
Thats it, that's all there is, and it's all contained in one file.
The script can be broken down into 5 distinct parts:
Here is where the administrator can set the few options associated with this script. He can choose to restrict voting voting against ip address and a number of times a single ip can vote, set the messages returned from the script, set the generic rating title text, and the end of line character to use when storing data in the text files (usefull for differing operating systems).
When the user selects a rating and hits the 'Rate' button, the script will extract the selected rating (performed by the while loop), get the user' ip address, and if the admin has chosen to apply ip voting restriction check to see if the user has already voted. If the user has already voted, it will check to see if the user has exhausted their voting allowance, and if so it will display the already voted message. If the vote is allowed, then the script will compile a short string containing the vote value and the ip address of the voter. This string will then be appended to the rating file for the particular item, and a thank you message will be displayed.
This portion of code will first check to see if there is a rating file for itself to use, and if not it will create one. If there is a file, the code opens it, extracts the number of votes and sums the value of each, then calculates the current rating by dividing the sum by the number of votes. This value is then limited to 2 decimal places.
Here the code takes the value of the sum as described above, and sets the image to use in the displayed output.
This is where the Microformat hReview is compiled and displayed including the rating selector, the rate button, the stars image, and any message that is to be displayed. The only non standard bit here would be
src="'.$rater_stars.'?x='.uniqid((double)microtime()*1000000,1).'"
as applied to the stars image. The reason for this is overcome image caching issues that were discovered during development.
All of the above code should be placed into one file (that I am calling rater.php). That file can then be called (or included) into any php page in the following way:
<?
$rater_id=1;
$rater_item_name='Item 1';
include("rater.php");
?>
This can be placed wherever you wish the rater to appear. To have more than one rater on any page simply do the following:
<?
$rater_id=1;
$rater_item_name='Item 1';
include("rater.php");
?>
<?
$rater_id=2;
$rater_item_name='Item 2';
include("rater.php");
?>
etc...
It really couldn't be more simple.
To help you along the way, we have zipped up some stars for you to use, and also within the zip is a file called rater.php which is all that is described above, and test.php which is an example of how to call the script. Simply unzip this file on to a webserver and lunch one of the files to see it in action. Note: you will need to make sure that you have write permissions in the directory in which the script is being used.
Download rater.zip
Here is an example of the script in action: Rater Example
Well none really. I honestly can't think of how to make this easier than it already is, both to use and to install. So please feel free to use the script wherever and whenever you like, but please do leave a comment so we can see it being used for real.
Also we would love to hear of any changes or improvements you make to the script.
Grow will ONLY support installs where the code has not been changed from what is presented here.
Use RSS to be notified when we publish an article. What is RSS?
Comments:
Comments are turned off for this article.