I want a loop, that echoes some football matches and my users bets on them, and then the possibillity to change the bets.
I have two tables in my db:
vm_kampe which is the matches where res is the result:
|id |hhold |uhold |res |
|1 |Rusland |Saudi |NULL |
|2 |Egypten |Uruguay |NULL |
... and so on
and vm_kampe, which is the users bets:
|id |resu |
|1 |2-1 |
|2 |1-3 |
... and so on.
My update site is like this:
SELECT * FROM vm_kampe k JOIN vm_207 u ON k.id = u.id
...
foreach($results as $row){
echo '<div class="vm_kupon_row">
<div class="vm_id"><input type="hidden" name="kampids[]" value="'.$row->id.'"></div>
<div class="vm_kampe">'.$row->hhold.' - '.$row->uhold.'</div>
<div class="vm_result"><input class="vm_resultat" type="text" name="resultats['.$row->id.']" placeholder="X-X" value="'.$row->resu.'"></div>
<input type="submit" class="godkend-vm-kupon" name="submit['.$row->id.']" value="Godkend">
My POST site is like this:
$res = $mysqli->real_escape_string($_POST['resultats']);
$id = $mysqli->real_escape_string($_POST['kampids']);
FOREACH ($_POST as $p) {
$gid = $p['id'];
$result = $p['res'];
$sql = "UPDATE vm_207 SET resu = '$result' WHERE id = '$gid'";
};
But if I try editting a bet and press submit, the bet will just stay the same as before. All I want is for me to be able to update every match. Please help :)
UPDATE
I just tried this in the post code:
$id = $_POST['kampids'];
$res = $_POST['resultats'];
foreach ( $id as $key => $k) {
print "The match is " .$k. " and the result is " .$res[$key];
};
I tried writing 2-1 in the first game and the print was:
The match is 1 and the result is 2-1
The match is...
So as I can see, the function works, so now I just need it to update the table..
In your hidden field, you are not setting the index number statically like you are with the other inputs.
<div class="vm_id"><input type="hidden" name="kampids['.$row->id.']" value="'.$row->id.'"></div>
I think this question / answer should help.
How to get form input array into PHP array
Related
I am a newbie to PHP and I am stuck at a certain point. I tried looking up a solution for it however, I didn't find exactly what I need.
My goal is to create a leaderboard, in which the values are displayed in descending order plus the rank and score are displayed. Furthermore, it should also display whether or not a tie is present.
The database should look like this:
+---------+------+----------------+-------+------+
| user_id | name | email | score | tied |
+---------+------+----------------+-------+------+
| 1 | SB | sb#gmail.com | 1 | 0 |
+---------+------+----------------+-------+------+
| 2 | AS | as#web.de | 2 | 0 |
+---------+------+----------------+-------+------+
| 3 | BR | br#yahoo.com | 5 | 1 |
+---------+------+----------------+-------+------+
| 4 | PJ | pj#gmail.com | 5 | 1 |
+---------+------+----------------+-------+------+
And the outputted table should look something like this:
+------+-------------+-------+------+
| rank | participant | score | tied |
+------+-------------+-------+------+
| 1 | BR | 5 | Yes |
+------+-------------+-------+------+
| 2 | PJ | 5 | Yes |
+------+-------------+-------+------+
| 3 | AS | 2 | No |
+------+-------------+-------+------+
| 4 | SB | 1 | No |
+------+-------------+-------+------+
I managed to display the rank, participant and the score in the right order. However, I can't bring the tied column to work in the way I want it to. It should change the value, whenever two rows (don't) have the same value.
The table is constructed by creating the <table> and the <thead> in usual html but the <tbody> is created by requiring a php file that creates the table content dynamically.
As one can see in the createTable code I tried to solve this problem by comparing the current row to the previous one. However, this approach only ended in me getting a syntax error. My thought on that would be that I cannot use a php variable in a SQL Query, moreover my knowledge doesn't exceed far enough to fix the problem myself. I didn't find a solution for that by researching as well.
My other concern with that approach would be that it doesn't check all values against all values. It only checks one to the previous one, so it doesn't compare the first one with the third one for example.
My question would be how I could accomplish the task with my approach or, if my approach was completely wrong, how I could come to a solution on another route.
index.php
<table class="table table-hover" id="test">
<thead>
<tr>
<th>Rank</th>
<th>Participant</th>
<th>Score</th>
<th>Tied</th>
</tr>
</thead>
<tbody>
<?php
require("./php/createTable.php");
?>
</tbody>
</table>
createTable.php
<?php
// Connection
$conn = new mysqli('localhost', 'root', '', 'ax');
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
// SQL Query
$sql = "SELECT * FROM names ORDER BY score DESC";
$result = $conn->query("$sql");
// Initalizing of variables
$count = 1;
$previous = '';
while($row = mysqli_fetch_array($result)) {
$current = $row['score'];
$index = $result['user_id']
if ($current == $previous) {
$update = "UPDATE names SET tied=0 WHERE user_id=$index";
$conn->query($update);
}
$previous = $current;
?>
<tr>
<td>
<?php
echo $count;
$count++;
?>
</td>
<td><?php echo $row['name'];?></td>
<td><?php echo $row['score'];?></td>
<td>
<?php
if ($row['tied'] == 0) {
echo 'No';
} else{
echo 'Yes';
}
?>
</td>
</tr>
<?php
}
?>
I think the problem is here
$index = $result['user_id'];
it should be
$index = $row['user_id'];
after updating tied you should retrieve it again from database
So I solved my question by myself, by coming up with a different approach.
First of all I deleted this part:
$current = $row['score'];
$index = $result['user_id']
if ($current == $previous) {
$update = "UPDATE names SET tied=0 WHERE user_id=$index";
$conn->query($update);
}
$previous = $current;
and the previous variable.
My new approach saves the whole table in a new array, gets the duplicate values with the array_count_values() method, proceeds to get the keys with the array_keys() method and updates the database via a SQL Query.
This is the code for the changed part:
// SQL Query
$sql = "SELECT * FROM names ORDER BY score DESC";
$result = $conn->query("$sql");
$query = "SELECT * FROM names ORDER BY score DESC";
$sol = $conn->query("$query");
// initalizing of variables
$count = 1;
$data = array();
// inputs table into an array
while($rows = mysqli_fetch_array($sol)) {
$data[$rows['user_id']] = $rows['score'];
}
// -- Tied Column Sort --
// counts duplicates
$cnt_array = array_count_values($data);
// sets true (1) or false (0) in helper-array ($dup)
$dup = array();
foreach($cnt_array as $key=>$val){
if($val == 1){
$dup[$key] = 0;
}
else{
$dup[$key] = 1;
}
}
// gets keys of duplicates (array_keys()) and updates database accordingly ($update query)
foreach($dup as $key => $val){
if ($val == 1) {
$temp = array_keys($data, $key);
foreach($temp as $k => $v){
$update = "UPDATE names SET tied=1 WHERE user_id=$v";
$conn->query($update);
}
} else{
$temp = array_keys($data, $k);
foreach($temp as $k => $v){
$update = "UPDATE names SET tied=0 WHERE user_id=$v";
$conn->query($update);
}
}
}
Thank you all for answering and helping me get to the solution.
instead of the update code you've got use something simular
$query = "select score, count(*) as c from names group by score having c > 1";
then you will have the scores which have a tie, update the records with these scores and your done. Make sure to set tie to 0 at first for all rows and then run this solution
UPDATE for an even faster solution sql based:
First reset the database:
$update = "UPDATE names SET tied=0";
$conn->query($update);
All records have a tied = 0 value now. Next update all the records which have a tie
$update = "update docs set tied = 1 where score IN (
select score from docs
group by score having count(*) > 1)";
$conn->query($update);
All records with a tie now have tied = 1 as we select all scores which have two or more records and update all the records with those scores.
I have a dynamic Matrix box where users can unlimited drugs, the data comes through like this:
[addindividuals] => [{"Drug":"Calpol","Strength":"100mg","Form":"Liquid","Quantity":"1"},{"Drug":"Paracetamol","Strength":"200mg","Form":"Tablet","Quantity":"16"}]
What I'm trying to achieve is to have each line inserted into a new row (MySQL) and inserts into their relevant columns like so:
Columns: | Drug | Strength | Form | Quantity
Row1 | Calpol | 100mg | Liquid | 1
Row2 |Paracetamol | 200mg | Tablet | 16
I'm guessing its using the exploded function> (I'm a novice) and then sql to insert the strings?
If you have the values as a json string collection, First you need to explode then the string then use a for each to loop through each string then use another for each to make single row. Please have a below code this may help you.
$addindividuals = '{"Drug":"Calpol","Strength":"100mg","Form":"Liquid","Quantity":"1"},{"Drug":"Paracetamol","Strength":"200mg","Form":"Tablet","Quantity":"16"}';
$exploded_array = explode('},',$addindividuals);
$final_query = "INSERT INTO `table_name` (`Drug`,`Strength`,`Form`,`Quantity`) VALUES ";
$exploded_array[0] = $exploded_array[0].'}';
foreach($exploded_array as $exploded_element)
{
$single_row = '(';
$json_decode = json_decode($exploded_element,true);
foreach($json_decode as $key => $value)
{
$single_row .= "'$value',";
}
$single_row = substr($single_row,0,-1);
$single_row .= '),';
$final_query .= $single_row;
}
$final_query = substr($final_query,0,-1);
echo $final_query;
I have form with a multiple selection, which has MySQL table column names as dynamic options.
<select id="rankRights" size="10" class="form-control" name="rights[]" multiple>
<?php
$sql = $pdo->query("SELECT * FROM ranks");
$rights = $sql->fetch(PDO::FETCH_ASSOC);
foreach($rights as $key => $value) {
if($key != 'Name' || $key != 'Id') {
echo "<option value=\"".$key."\"";
if($result[$key] == '1') {
echo " selected";
}
echo "> " . $key . "</option>";
}
}
?>
</select>
And in table there is user rights as columns and value 1 or 0 (means true or false, example below). There can be any number of columns.
.--------------------------------------------------------------------------------.
| Id | Name | ADMIN | ADMIN_EDITUSER | ADMIN_DELETEUSER | etc |
'--------------------------------------------------------------------------------'
| 1 | Admin | 1 | 1 | 1 | ... |
| 2 | Default | 0 | 0 | 0 | ... |
'--------------------------------------------------------------------------------'
What I want to do is update the values to 1 if user has selected column name in multiple selection and vice versa. How can I post those to the PDO query..
EDIT: So, if I submit the form (for example selected ADMIN and ADMIN_EDITUSER from multiple selection), I'll get POST params like rights[]=ADMIN and rights[]=ADMIN_EDITUSER -> in that case I want to update values of columns ADMIN and ADMIN_EDITUSER to 1, and values of all other columns (options not selected) to 0.
I have read following questions and thinking something, but I don't even now know how to do this.
You could create an array of permission/column names:
$names = array('ADMIN','ADMIN_EDITUSER',...);
Initialize permissions to zero:
$permval = array();
foreach ($names as $name)
$permval[$name] = 0;
Walk the posted values to set related permissions:
foreach ($_REQUEST as $key => $value)
{
if ( isset($permval[$key]) )
$permval[$key] = $value;
}
This at least gives you a defined list of values that you use can use to bind to a set of parameters - one for each permission name. Ensure the list of permission names and a statement preparation are kept in sync.
Any easier alternative may be to create a SQL statement on the fly but you may prefer to use PDO.
NOTE: I did not attempt to execute any of the above; it may contain typos!
Here is my database:
id | liker | ques_id
1 | 15 | 2342
2 | 22 | 2342
3 | 22 | 2311
4 | 15 | 2389
What I need to get is all the liker's who have liked ques_id. So the result should look something like this:
Question 2342 has been liked by 15 and 22.
Question 2311 has been liked by 22 and so on
My current code produces separate row for each liker and ques_id:
$sqlq=mysql_query("SELECT * FROM likes");
while($rowq=mysql_fetch_array($sqlq)){
$qid=$rowq['ques_id'];
$sql=mysql_query("SELECT * FROM likes where ques_id='$qid'");
$num=mysql_num_rows($sql);
$cont='';
while($row=mysql_fetch_array($sql)){
$liker=$row['liker'];
$cont .="$qid being liked by $liker<br>";
}
echo $cont;
}
I haven't tested this but it should get you started:
$sqlq=mysql_query("SELECT DISTINCT(ques_id) FROM likes");
$cont='';
while($rowq=mysql_fetch_array($sqlq)){
$qid=$rowq['ques_id'];
$sql=mysql_query("SELECT * FROM likes where ques_id='$qid'");
$num=mysql_num_rows($sql);
$row=mysql_fetch_array($sql)
$cont .= "$qid being liked by $liker ";
while($row=mysql_fetch_array($sql)){
$liker=$row['liker'];
$cont .= " and $liker";
}
$cont .= ".<br>";
}
echo $cont;
You need no second query to DB, it enough iterate only first result.
For example, you may collect all the likers, that match a specific ques_id in a assoc array with keys are ques_id, like this:
$mathces = array();
$sqlq=mysql_query("SELECT * FROM likes");
while($rowq=mysql_fetch_array($sqlq)){
$qid=$rowq['ques_id'];
$liker=$rowq['liker'];
$matches[ $qid ][] = $liker;
}
Then, you may foreach $mathces array and build you string.
foreach ($matches as $qid => $likers) {
$cont .= "$qid being liked by " . implode(' and ', $likers );
if (count($likers) == 1)
$cont .= ' and so on';
echo "$cont<br>";
}
I didn't test my code. It need to additional validations (e.g. for $linkers in second loop)
SELECT GROUP_CONCAT(liker), ques_id FROM likes GROUP BY ques_id
That will pull each liker grouped together for each ques_id.
You then only have to process the rows returned.
You should steer clear of the mysql extension as it is deprecated; use PDO or mysqli instead.
$sql = 'SELECT GROUP_CONCAT(liker) as likes, ques_id FROM likes GROUP BY ques_id';
foreach ($conn->query($sql) as $row) {
printf('Question %s is liked by %s', $row['ques_id'], $row['likes']);
}
I have two tables-food and tags. Each row from food has corresponding tags.
I want to output each row with those tags, ie:
table food:
id | name
1 | bread
2 | meat
table tags:
reference_id | tag
1 | bakery
1 | wheat
2 | cow
desired output is:
{"results":
[{"id":"1","name":"bread","tags":["bakery","wheat"]},
{"id":"2","name":"meat","tags":["cow"]}]
}
So far I have this:
$db = getConnection();
$stmt = $db->query($sql);//get every column from every food
$food = $stmt->fetchAll(PDO::FETCH_OBJ);
$tagsSql="select id_reference,tag FROM tags T,food F WHERE F.id=T.food_id_reference";
$stmt = $db->query($tagsSql);
$tags=$stmt->fetchAll(PDO::FETCH_OBJ);
echo '{"results":' . json_encode($food) . '}';
I was thinking about cycling through every food and ever tag and find matching pairs, but it seems pretty heavyweight to me (considering the fact, that I could have thousands of rows). Do you have any suggestions?
Untested but I think something like this should work for you
$db = getConnection();
$stmt = $db->query($sql);//get every column from every food
$tagsSql="select F.id as id, F.name as name, group_concat(T.tag SEPARATOR ',') as tags FROM tags T,feeds F WHERE F.id=T.feed_id_reference group by feed_id_reference";
$stmt = $db->query($tagsSql);
for($x = 0; $x < count($tags); $x++){
$tags[$x]->{"tags"} = explode(",", $tags[$x]->{"tags"});
echo '{"results":' . json_encode($tags) . '}';
}