I have codes that should be getting value from mysql database, I can get only one value but I have while loop so it can get value and output data separated with comma. But I only get one value and cannot get multiple value. the result should be like this, // End main PHP block. Data looks like this: [ [123456789, 20.9],[1234654321, 22.1] ] here is the code:
<?php
// connect to MySQL
mysql_connect('localhost','','') or die("Can't connect that way!");
#mysql_select_db('temperature1') or die("Unable to select a database called 'temperature'");
if(ISSET($_GET['t']) && (is_numeric($_GET['t'])) ){
// message from the Arduino
$temp = $_GET['t'];
$qry = "INSERT INTO tempArray(timing,temp) VALUES(".time().",'$temp')";
echo $qry;
mysql_query($qry);
mysql_close();
exit('200');
}
// no temp reading has been passed, lets show the chart.
$daysec = 60*60*24; //86,400
$daynow = time();
if(!$_GET['d'] || !is_numeric($_GET['d'])){
$dayoffset = 1;
} else {
$dayoffset = $_GET['d'];
}
$dlimit = $daynow-($daysec*$dayoffset);
$qryd = "SELECT id, timing, temp FROM tempArray WHERE timing>='$dlimit' ORDER BY id ASC LIMIT 1008";
// 1008 is a weeks worth of data,
// assuming 10 min intervals
$r = mysql_query($qryd);
$count = mysql_num_rows($r);
$i=0;
$r = mysql_query($qryd);
$count = mysql_num_rows($r);
while($row=mysql_fetch_array($r, MYSQL_ASSOC)) {
$tid=$row['id'];
$dt = ($row['timing']+36000)*1000;
$te = $row['temp'];
if($te>$maxtemp) $maxtemp=$te; // so the graph doesnt run along the top
if($te<$mintemp) $mintemp=$te; // or bottom of the axis
$return="[$dt, $te]";
echo $return; //here I get all values [1385435831000, 21][1385435862000, 23][1385435892000, 22][1385435923000, 25][1385435923000, 22]
$i++;
if($i<$count) $return= ","; echo $return; // if there is more data, add a ',' however, it return me ,,,[1385435923000, 22]
$latest = "$dt|$te"; // this will get filled up with each one
}
mysql_close();
// convert $latest to actual date - easier to do it here than in javascript (which I loathe)
$latest = explode('|',$latest);
$latest[0] = date('g:ia, j.m.Y',(($latest[0])/1000)-36000);
?>
You're just assigning $return to the values from the last row your while loop grabbed instead of concatenating it. Try this
$return = "[";
while($row=mysql_fetch_array($r, MYSQL_ASSOC)) {
$tid=$row['id'];
$dt = ($row['timing']+36000)*1000;
$te = $row['temp'];
if($te>$maxtemp) $maxtemp=$te; // so the graph doesnt run along the top
if($te<$mintemp) $mintemp=$te; // or bottom of the axis
$return.="[$dt, $te]";
$i++;
if($i<$count) $return .= ", ";// if there is more data, add a ','
$latest = "$dt|$te"; // this will get filled up with each one
}
$return .= "]";
I have two queries sent to a database bring back posts (op_ideas 16 cols) followed by another which holds the votes per post (op_idea_vote cols 4) with matching idea_id's
Example of Data:
Query: op_ideas:
[{"idea_id":"2211","author_id":"100000", "date":"2012-09-06
10:02:28","idea_title":"Another test","4" etc etc
Query: op_idea_votes:
idea_id = 2211, agree=3, disagree=1, abstain=0
The code below ought to look at op_ideas, and then cycle over op_ideas_vote until it finds a match under 'idea_id'. Then it goes to the next record under op_ideas, and again using that idea_id search for it within the op_idea_vote list, find a match, and add it to the array.
This works for only the first record, not for the other three. I am testing, so I have 3 rows in each that match idea_id with different results in the op_idea_vote.
$votes = mysql_query($commentVotes);
$result = mysql_query($gl_query);
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes= mysql_fetch_array($votes)) {
if($voteid = $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
//print_r($gce_result);
}
$data_result[] = $gce_result;
}
echo json_encode($data_result);
If I use print_f(&gce_result) it works fine in phpfiddle. But when i use the code above, it works for the first record, but it's complete missing the second two. It seems to be missing the second while, as it does not even give me the 0 0 0 results.
Query for op_ideas:
$gl_query = "SELECT DISTINCT * FROM heroku_056eb661631f253.op_ideas INNER JOIN op_organs ORDER BY date ASC;";
if (!mysql_query($gl_query)) {
die('Error: ' . $gl_query . " " . mysql_error());
}
$result = mysql_query($gl_query);
Query For op_idea_vote :
$commentVotes = "SELECT v.idea_id, COUNT(v.agree = 1 or null) as agree, COUNT(v.disagree = 1 or null) as disagree, COUNT(v.obstain = 1 or null) as obstain FROM op_idea_vote v GROUP BY v.idea_id";
if (!mysql_query($commentVotes)) {
die('Error: ' . $commentVotes . " " . mysql_error());
}
$votes = mysql_query($commentVotes);
You can scan a resource only once.
So the inner while will be run only one time.
use == instead of = for checking condition of if & while
in the while loop ,you have to assign the value of $allvotes ,but you never assigned,
while ($gce_result == mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
while($allvotes== mysql_fetch_array($votes)) {
if($voteid == $allvotes['idea_id'])
{
//echo $voteid . " main idea and the votes: " . $allvotes;
$gce_result["agree"] = $allvotes['agree'];
$gce_result["disagree"] = $allvotes['disagree'];
$gce_result["abstain"] = $allvotes['obstain'];
}
else
{
$gce_result["agree"] = 0;
$gce_result["disagree"] = 0;
$gce_result["abstain"] = 0;
}
$data_result[] = $gce_result;
}
}
Your problem is trying to scan over the $votes result more than once.
You should store the result of that query first.
Eg.
while ($vote = mysql_fetch_array($votes)) {
$allvotes['idea_id'] = $vote;
}
while ($gce_result = mysql_fetch_array($result)) {
$voteid = $gce_result['idea_id'];
if (array_key_exists[$voteid, $allvotes]) {
//assign results
} else {
//default
}
}
Another option would be to do the query with a join, so you can do everything in one query. Then just loop over that result.
I currently have a php page that grabs information from a database and produces HTML with data attributes that are filled in by from the MySQL query. The database is going to be used to search, with many different options for searches.
What I need help with is knowing a way so to organize how the many variables are handled. It's a really big mess of code, and even with all the comments I put it gives me a headache trying to figure out how to add another variable to the search.
All the variables, except for the LIMIT to which row and how many results, are optional. So if someone leaves everything except that blank, I still want it to function as well as if they meticulously filled in all the fields.
Here's what I have, with 6 variables.
<?php
$product_size = "(".$_GET['size']." BETWEEN productsizeDOWN AND productsizeUP)"; // This code sets the variable to input into the MySQL string based on the URL
$product_size_check = $_GET['size']; // the _checks check are used to see if the value is or isn't empty using if statements below
$manufacturer = $_GET['manufacturer'];
$product_manufacterer_check = $_GET['manufacturer']; // _check
$product_invisible = "(hideproduct = '".$_GET['invisible']."')"; // Checks if product is hidden
$product_invisible_check = $_GET['invisible']; // _check
$product_instock_check = $_GET['instock']; // _check
$product_limit0 = $_GET['startat']; // This is the first number after LIMIT; the row to start in.
$product_limit1 = $_GET['results']; // This is how many results to load.
$manufacturer_array = explode(",", $manufacturer); // The manufacturer comes in as "Nike,Addidas,Rebok" and is turned into an array
$manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_array); // Puts it back together with "OR productmanufacturer =" between each name.
$product_manufacterer = ("(productmanufacturer = '".$manufacturer_imploded."')"); // formats it so it can be directly inserted into MySQL string with a WHERE in front.
if($product_invisible_check == ""){
$product_invisible = "";
}else{$where = "WHERE ";}; //Useless code that I havn't deleted that I tried to use when I searched the entire database
if($product_size_check == ""){
$product_size = "";
}else{$where = "WHERE ";};
if($product_manufacterer_check == ""){
$product_manufacterer = "";
}else{$where = "WHERE ";};
if($product_instock_check == "N"){
$product_instock = "(stockstatus <= '0' AND donotallowbackorders = 'Y') AND "; // Checks if product is in stock (Allowing backordering OR stock >1)
$where = "WHERE ";
}
elseif($product_instock_check == "Y") {
$product_instock = "(stockstatus > '0' OR donotallowbackorders = 'N') AND ";
$where = "WHERE ";
}
else {
$product_instock = "";
};
$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." LIMIT ".$product_limit0.", ".$product_limit1; // The end result of it all.
echo $sql;
?>
When the URL is
test.php?size=5&manufacturer=Nike,Addidas,Rebok&invisible=N&instock=Y&startat=0&results=30
the resulting SQL query is
Select * FROM ioa7pd_Products WHERE (stockstatus > '0' OR donotallowbackorders = 'N') AND (5 BETWEEN productsizeDOWN AND productsizeUP)AND(productmanufacturer = 'Nike' OR productmanufacturer = 'Addidas' OR productmanufacturer = 'Rebok')(hideproduct = 'N') LIMIT 0, 30
But I plan to add more options to the search.
My main question is simply: What way can I organize this to make it simple to add more variables? Tiered if statements?
Travesty has been helping me with my code and has really been great in organizing it.
Here is the current code. It needs to be secure to prevent injection.
// Database connection
$con = mysql_connect("[CENSORED]","[CENSORED]","[CENSORED]")
or die("Could not connect: " . mysql_error());
mysql_select_db("[CENSORED]") or die('Could not select database');
// Begin organization of URL variables into MYSQL Query
$get_size = $_GET['size'];
$get_manufacturer = $_GET['manufacturer'];
$get_invisible = $_GET['invisible'];
$get_instock = $_GET['instock'];
$get_sex = $_GET['sex'];
$get_startat = $_GET['startat'];
$get_results = $_GET['results'];
if ($get_size != ""){
$all_selectors[] = "(".$get_size." BETWEEN productsizeDOWN AND productsizeUP)"; // Add to array if size is not blank.
};
if ($get_manufacturer != ""){
$manufacturer_exploded = explode(",", $get_manufacturer);
$manufacturer_imploded = implode("' OR productmanufacturer = '", $manufacturer_exploded);
$all_selectors[] = ("(productmanufacturer = '".$manufacturer_imploded."')");
};
if ($get_invisible != ""){
$all_selectors[] = "(hideproduct = '".$get_invisible."')";
};
if($get_instock == "N" or $get_instock == "n"){
$all_selectors[] = "(stockstatus <= '0' AND donotallowbackorders = 'Y')";
}elseif($get_instock == "Y" or $get_instock == "y") {
$all_selectors[] = "(stockstatus > '0' OR donotallowbackorders = 'N')";
};
if ($get_startat != "" or $get_results != ""){
$number_results = "LIMIT ".$get_startat.", ".$get_results;
} else {
$number_results = "LIMIT 0, 15";
};
// All variables are now in an array, except "startat" and "results"
$all_selectors0 = "WHERE ".implode(" AND ", $all_selectors);
// Create SQL query
$sql="Select * FROM sadsads_Products ".$all_selectors0." ".$number_results;
I would do something more like this. It's not tested and probably not 100% complete...you may need to do some further customization, particularly with adding more special cases to the switch statement, but this will make adding more variables much easier:
REMOVED OLD EXAMPLE, SEE UPDATED EXAMPLE BELOW
One key thing to note is that you aren't sanitizing your database inputs. Your code is vulnerable to SQL injection. My example above helps to solve that, but this code isn't fully tested, so you should ensure that all user input is sanitized before using it in any query.
If your field names don't match up with your MySQL columns (which it looks like they don't), then you can fix them with an associative array:
$columns = array(
// [form field] => [mysql column]
'size' => 'product_size',
'manufacturer' => 'product_manufacturer',
'invisible' => 'hideproduct'
// ...
);
And then in your switch statement, do something more like this:
$whereClause[] = "{$columns[$key]} = '{$value}'";
FINAL UPDATE:
DOCUMENTED SAMPLE - has plenty of comments and extra stuff to make it work on Codepad
EXACT WORKING CODE - you should be able to copy and paste this (and add your DB credentials) and it should work:
$con = mysqli_connect("[CENSORED]", "[CENSORED]", "[CENSORED]") or die("Could not connect: ". mysqli_error());
mysqli_select_db("[CENSORED]") or die("Could not select database");
$columns = array(
'size' => 'product_size',
'manufacturer' => 'product_manufacturer',
'invisible' => 'hideproduct'
);
$whereClause = array();
$limit = array("startat" => 0, "results" => 15);
foreach ($_GET as $key=>$value) {
$key = mysqli_real_escape_string($key);
if (is_array($value)) {
for ($i = 0; $i < count($value); $i++) {
$value[$i] = mysqli_real_escape_string($value[$i]);
}
} else {
$value = mysqli_real_escape_string($value);
}
switch ($key) {
case 'size':
$whereClause[] = "({$value} BETWEEN productsizeDOWN AND productsizeUP)";
break;
case 'startat':
case 'results':
$limit[$key] = $value;
break;
case 'instock':
$whereClause[] = "(stockstatus ". ($value == 'N' ? "<=" : ">") ." '0' ". ($value == 'N' ? "AND" : "OR") ." donotallowbackorders = '". ($value == 'N' ? "Y" : "N") ."')";
break;
default: {
if (is_array($value)) {
$whereClause[] = "{$columns[$key]} IN ('". implode("', '", $value) ."')";
} else {
$whereClause[] = "{$columns[$key]} = '{$value}'";
}
}
}
}
$sql = "SELECT * FROM ioa7pd_Products". (empty($whereClause) ? "" : " WHERE ". implode(" AND ", $whereClause)) ." LIMIT {$limit['startat']}, {$limit['results']}";
echo $sql;
after
else {
$product_instock = "";
};
do:
$limit = '';
if( !empty($product_limit0) && !empty($product_limit1) )
$limit = " LIMIT $product_limit0, $product_limit1";
$sql="Select * FROM ioa7pd_Products WHERE ".$product_instock.$product_size."AND".$product_manufacterer_and.$product_manufacterer."".$product_invisible." $limit"; // The end result of it all.
echo $sql;
If you have separate params in $_GET, you would have to traverse with multiple if statements. you can pass the params as an array into $_GET, with numeric keys, that would help a bunch.
We currently have a voting system setup that saves the IP address of the person making a vote to stop duplicate votes.
However everyday the IP address is removed from the database so they can re-vote on there favourite item.
Looking through the code below can you see how I can stop this so that a person with a certain IP address can never vote for that certain item again? They are however able to vote on the other entrants, but again only vote once.
Any ideas?
<?php
// Script Voting - http://www.coursesweb.net/
class Voting {
// properties
static protected $conn = false; // stores the connection to mysql
public $affected_rows = 0; // number of affected, or returned rows in SQL query
protected $voter = ''; // the user who vote, or its IP
protected $nrvot = 0; // if it is 1, the user can vote only one item in a day, 0 for multiple items
protected $svoting = 'mysql'; // 'mysql' to register data in database, any other value register in TXT files
public $votitems = 'voting'; // Table /or file_name to store items that are voted
public $votusers = 'votusers'; // Table /or filename that stores the users who voted in current day
protected $tdy; // will store the number of current day
public $eror = false; // to store and check for errors
// constructor
public function __construct() {
// sets $nrvot, $svoting, $voter, and $tdy properties
if(defined('NRVOT')) $this->nrvot = NRVOT;
if(defined('SVOTING')) $this->svoting = SVOTING;
if(defined('USRVOTE') && USRVOTE === 0) { if(defined('VOTER')) $this->voter = VOTER; }
else $this->voter = $_SERVER['REMOTE_ADDR'];
$this->tdy = date('j');
// if set to use TXT files, set the path and name of the files
if($this->svoting != 'mysql') {
$this->votitems = '../votingtxt/'.$this->votitems.'.txt';
$this->votusers = '../votingtxt/'.$this->votusers.'.txt';
}
}
// for connecting to mysql
protected function setConn() {
try {
// Connect and create the PDO object
self::$conn = new PDO("mysql:host=".DBHOST."; dbname=".DBNAME, DBUSER, DBPASS);
// Sets to handle the errors in the ERRMODE_EXCEPTION mode
self::$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$conn->exec('SET CHARACTER SET utf8'); // Sets encoding UTF-8
}
catch(PDOException $e) {
$this->eror = 'Unable to connect to MySQL: '. $e->getMessage();
}
}
// Performs SQL queries
public function sqlExecute($sql) {
if(self::$conn===false OR self::$conn===NULL) $this->setConn(); // sets the connection to mysql
$re = true; // the value to be returned
// if there is a connection set ($conn property not false)
if(self::$conn !== false) {
// gets the first word in $sql, to determine whenb SELECT query
$ar_mode = explode(' ', trim($sql), 2);
$mode = strtolower($ar_mode[0]);
// performs the query and get returned data
try {
if($sqlprep = self::$conn->prepare($sql)) {
// execute query
if($sqlprep->execute()) {
// if $mode is 'select', gets the result_set to return
if($mode == 'select') {
$re = array();
// if fetch() returns at least one row (not false), adds the rows in $re for return
if(($row = $sqlprep->fetch(PDO::FETCH_ASSOC)) !== false){
do {
// check each column if it has numeric value, to convert it from "string"
foreach($row AS $k=>$v) {
if(is_numeric($v)) $row[$k] = $v + 0;
}
$re[] = $row;
}
while($row = $sqlprep->fetch(PDO::FETCH_ASSOC));
}
$this->affected_rows = count($re); // number of returned rows
}
}
else $this->eror = 'Cannot execute the sql query';
}
else {
$eror = self::$conn->errorInfo();
$this->eror = 'Error: '. $eror[2];
}
}
catch(PDOException $e) {
$this->eror = $e->getMessage();
}
}
// sets to return false in case of error
if($this->eror !== false) { echo $this->eror; $re = false; }
return $re;
}
// returns JSON string with item:['vote', 'nvotes', renot] for each element in $items array
public function getVoting($items, $vote = '') {
$votstdy = $this->votstdyCo($items); // gets from Cookie array with items voted by the user today
// if $vote not empty, perform to register the vote, $items contains one item to vote
if(!empty($vote)) {
// if $voter empty means user not loged
if($this->voter === '') return "alert('Vote Not registered.\\nYou must be logged in to can vote')";
else {
// gets array with items voted today from mysql, or txt-files (according to $svoting), and merge unique to $votstdy
if($this->svoting == 'mysql') {
$votstdy = array_unique(array_merge($votstdy, $this->votstdyDb()));
}
else {
$all_votstdy = $this->votstdyTxt(); // get 2 array: 'all'-rows voted today, 'day'-items by voter today
$votstdy = array_unique(array_merge($votstdy, $all_votstdy[$this->tdy]));
}
// if already voted, add in cookie, returns JSON from which JS alert message and will reload the page
// else, accesses the method to add the new vote, in mysql or TXT file
if(in_array($items[0], $votstdy) || ($this->nrvot === 1 && count($votstdy) > 0)) {
$votstdy[] = $items[0];
setcookie("votings", implode(',', array_unique($votstdy)), strtotime('tomorrow'));
return '{"'.$items[0].'":[0,0,3]}';
}
else if($this->svoting == 'mysql') $this->setVotDb($items, $vote, $votstdy); // add the new vote in mysql
else $this->setVotTxt($items, $vote, $all_votstdy); // add the new vote, and voter in TXT files
array_push($votstdy, $items[0]); // adds curent item as voted
}
}
// if $nrvot is 1, and $votstdy has item, set $setvoted=1 (user already voted today)
// else, user can vote multiple items, after Select is checked if already voted the existend $item
$setvoted = ($this->nrvot === 1 && count($votstdy) > 0) ? 1 : 0;
// get array with items and their votings from mysql or TXT file
$votitems = ($this->svoting == 'mysql') ? $this->getVotDb($items, $votstdy, $setvoted) : $this->getVotTxt($items, $votstdy, $setvoted);
return json_encode($votitems);
}
// insert /update rating item in #votitems, delete rows in $votusers which are not from today, insert $voter in $votusers
protected function setVotDb($items, $vote, $votstdy) {
$this->sqlExecute("INSERT INTO `$this->votitems` (`item`, `vote`) VALUES ('".$items[0]."', $vote) ON DUPLICATE KEY UPDATE `vote`=`vote`+$vote, `nvotes`=`nvotes`+1");
$this->sqlExecute("DELETE FROM `$this->votusers` WHERE `day`!=$this->tdy");
$this->sqlExecute("INSERT INTO `$this->votusers` (`day`, `voter`, `item`) VALUES ($this->tdy, '$this->voter', '".$items[0]."')");
// add curent voted item to the others today, and save them as string ',' in cookie (till the end of day)
$votstdy[] = $items[0];
setcookie("votings", implode(',', array_unique($votstdy)), strtotime('tomorrow'));
}
// select 'vote' and 'nvotes' of each element in $items, $votstdy stores items voted by the user today
// returns array with item:['vote', 'nvotes', renot] for each element in $items array
protected function getVotDb($items, $votstdy, $setvoted) {
$re = array_fill_keys($items, array(0,0,$setvoted)); // makes each value of $items as key with an array(0,0,0)
function addSlhs($elm){return "'".$elm."'";} // function to be used in array_map(), adds "'" to each $elm
$resql = $this->sqlExecute("SELECT * FROM `$this->votitems` WHERE `item` IN(".implode(',', array_map('addSlhs', $items)).")");
if($this->affected_rows > 0) {
for($i=0; $i<$this->affected_rows; $i++) {
$voted = in_array($resql[$i]['item'], $votstdy) ? $setvoted + 1 : $setvoted; // add 1 if the item was voted by the user today
$re[$resql[$i]['item']] = array($resql[$i]['vote'], $resql[$i]['nvotes'], $voted);
}
}
return $re;
}
// add /update rating item in TXT file, keep rows from today in $votusers, and add new row with $voter
protected function setVotTxt($items, $vote, $all_votstdy) {
// get the rows from file with items, if exists
if(file_exists($this->votitems)) {
$rows = file($this->votitems, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$nrrows = count($rows);
// if exist rows registered, get array for each row, with - item^vote^nvotes
// if row with item, update it and stop, else, add the row at the end
if($nrrows > 0) {
for($i=0; $i<$nrrows; $i++) {
$row = explode('^', $rows[$i]);
if($row[0] == $items[0]) {
$rows[$i] = $items[0].'^'.($row[1] + $vote).'^'.($row[2] + 1);
$rowup = 1; break;
}
}
}
}
if(!isset($rowup)) $rows[] = $items[0].'^'.$vote.'^1';
file_put_contents($this->votitems, implode(PHP_EOL, $rows)); // save the items in file
// add row with curent item voted and the voter (today^voter^item), and save all the rows
$all_votstdy['all'][] = $this->tdy.'^'.$this->voter.'^'.$items[0];
file_put_contents($this->votusers, implode(PHP_EOL, $all_votstdy['all']));
// add curent voted item to the others today, and save them as string ',' in cookie (till the end of day)
$all_votstdy[$this->tdy][] = $items[0];
setcookie("votings", implode(',', array_unique($all_votstdy[$this->tdy])), strtotime('tomorrow'));
}
// get from TXT 'vote' and 'nvotes' of each element in $items, $votstdy stores items voted by the user today
// returns array with item:['vote', 'nvotes', renot] for each element in $items array
protected function getVotTxt($items, $votstdy, $setvoted) {
$re = array_fill_keys($items, array(0,0,$setvoted)); // makes each value of $items as key with an array(0,0,0)
if(file_exists($this->votitems)) {
$rows = file($this->votitems, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$nrrows = count($rows);
// if exist rows registered, get array for each row, with - item^vote^nvotes
// if row with item is in $items, add its data in $re
if($nrrows > 0) {
for($i=0; $i<$nrrows; $i++) {
$row = explode('^', $rows[$i]);
$voted = in_array($row[0], $votstdy) ? $setvoted + 1 : $setvoted; // add 1 if the item was voted by the user today
if(in_array($row[0], $items)) $re[$row[0]] = array($row[1], $row[2], $voted);
}
}
}
return $re;
}
// gets and returns from Cookie an array with items voted by the user ($voter) today
protected function votstdyCo() {
$votstdy = array();
// if exists cookie 'votings', adds items voted today in $votstdy (array_filter() - removes null, empty elements)
if(isset($_COOKIE['votings'])) {
$votstdy = array_filter(explode(',', $_COOKIE['votings'])); // cookie stores string with: item1, item2, ...
}
return $votstdy;
}
// returns from mysql an array with items voted by the user today
protected function votstdyDb() {
$votstdy = array();
$resql = $this->sqlExecute("SELECT `item` FROM `$this->votusers` WHERE `day`=$this->tdy AND `voter`='$this->voter'");
if($this->affected_rows > 0) {
for($i=0; $i<$this->affected_rows; $i++) {
$votstdy[] = $resql[$i]['item'];
}
}
return $votstdy;
}
// returns from TXT file an array with 2 arrays: all rows voted today, and items voted by the user today
protected function votstdyTxt() {
$re['all'] = array(); $re[$this->tdy] = array();
if(file_exists($this->votusers)) {
$rows = file($this->votusers, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
$nrrows = count($rows);
// if exist rows registered, get array for each row, with - day^voter^item , compare 'day', and 'voter'
if($nrrows > 0) {
for($i=0; $i<$nrrows; $i++) {
$row = explode('^', $rows[$i]);
if($row[0] == $this->tdy) {
$re['all'][] = $rows[$i];
if($row[1] == $this->voter) $re[$this->tdy][] = $row[2];
}
}
}
}
return $re;
}
}
Make an SQL database of the IP addresses you want to ban, or if the list is short enough us an array.
Check if the IP address is in the database or array. If it's not allow them to vote. However, if it is let them think they voted put it in the database and make it as voted, but mark the vote as does not count so they will not try to get around your block.
This function seems to be deleting votes that are not from "today":
// insert /update rating item in #votitems, delete rows in $votusers which are not from today, insert $voter in $votusers
protected function setVotDb($items, $vote, $votstdy) {
$this->sqlExecute("INSERT INTO `$this->votitems` (`item`, `vote`) VALUES ('".$items[0]."', $vote) ON DUPLICATE KEY UPDATE `vote`=`vote`+$vote, `nvotes`=`nvotes`+1");
//$this->sqlExecute("DELETE FROM `$this->votusers` WHERE `day`!=$this->tdy");
$this->sqlExecute("INSERT INTO `$this->votusers` (`day`, `voter`, `item`) VALUES ($this->tdy, '$this->voter', '".$items[0]."')");
// add curent voted item to the others today, and save them as string ',' in cookie (till the end of day)
$votstdy[] = $items[0];
setcookie("votings", implode(',', array_unique($votstdy)), strtotime('tomorrow'));
}
I've commented out the delete query. You should test it out before putting it into production.
Your database structure seems a bit confusing, you have a table to count the vote per items and a table to count the vote per user.
You should review your database structure to merge those two tables in one table, with the : item, user, vote fields.
So you could keep a record for each vote of each user for each item as long as you want and eventualy make count() or sum() requests to get the total of votes per item