Recursive function does not display anything - php

I have a tree with nodes and I wanted to display every node's level in a table,
but when it does not display anything.
I tried to put a comment when I do: findlevel($_SESSION['id'], $level +1, $idtofind); at the end of the function, if I do that it works but only for the first level of the Tree.
My code:
function findlevel($parent_id, $level, $idtofind)
{
global $data, $index, $tree;
$parent_id = $parent_id === NULL ? "NULL" : $parent_id;
if (isset($index[$parent_id])) {
foreach ($index[$parent_id] as $id) {
$current_id = $data[$id]["id"];
$levell = $level+1;
if($current_id == $idtofind) {
echo $current_id . " " . $idtofind . $levell . "<br>";
return $levell;
}
findlevel($_SESSION['id'], $level + 1, $idtofind);
}
}
}
Code of my table:
$result = $conn->query("SELECT id, email, tipoutente, fullname, datainserimento, DATEDIFF(datainserimento, '$datainserimentosponsor') AS datadiff FROM utenti WHERE inseritoda = " . $_SESSION['id']);
while($row = mysqli_fetch_array($result)){
echo "<tr class=\"righe\">";
$levelnode =findlevel($_SESSION['id'], 0, $row['id']);
if($row['tipoutente'] == "GRUPPO PRIVATO" || $row['tipoutente'] == "GRUPPO NEGOZI" || $row['tipoutente'] == "GRUPPO ASSOCIAZIONI") {
echo "<td class=\"gruppi\">$progressivoutenti</td>";
echo "<td class=\"gruppi\">" . $row['fullname'] . "</td>";
echo "<td class=\"gruppi\">" . $row['email'] . "</td>";
echo "<td class=\"gruppi\">" . $row['tipoutente'] . "</td>";
echo "<td class=\"gruppi\">" . $row['datainserimento'] . "</td>";
echo "<td class=\"gruppi\">" . $row['datadiff'] . "</td>";
echo "<td class=\"gruppi\">" . $levelnode . "</td>";
//}
} else {
echo "<td class=\"dati\">$progressivoutenti</td>";
echo "<td class=\"dati\">" . $row['fullname'] . "</td>";
echo "<td class=\"dati\">" . $row['email'] . "</td>";
echo "<td class=\"dati\">" . $row['tipoutente'] . "</td>";
echo "<td class=\"dati\">" . $row['datainserimento'] . "</td>";
echo "<td class=\"dati\">" . $row['datadiff'] . "</td>";
echo "<td class=\"dati\">" . $levelnode . "</td>";
}
$progressivoutenti++;
echo "</tr>";
}
echo "</table>";
Edit:
This is the rest of the code:
$data = array();
$index = array();
$albero = array();
$query = $conn->query("SELECT * FROM utenti where utentepadre is not null order by fullname");
$query->data_seek(0);
while ($row = $query->fetch_assoc()) {
$id = $row["id"];
$parent_id = $row["utentepadre"] === NULL ? "NULL" : $row["utentepadre"];
$data[$id] = $row;
$index[$parent_id][] = $id;
}
That's how my tree looks like:
My Tree
And the result is:
The result of the php page.
The result of the variable $data:
Variable $data content

Related

Recursive Php function not working

I am trying to display in a table all the child nodes from an ID passed as a parameter. I used a recursive function in PHP to do that.
The only problem is that it displays only the 1st child and not all of them.
This is the Tree.
The PHP Function:
$data = array();
$index = array();
$albero = array();
$query = $conn->query("SELECT id, insertedby FROM utenti where insertedby is not null ORDER BY id");
$query->data_seek(0);
while ($row = $query->fetch_assoc()) {
$id = $row["id"];
$parent_id = $row["insertedby"] === NULL ? "NULL" : $row["insertedby"];
$data[$id] = $row;
$index[$parent_id][] = $id;
}
function findNodeLevel($parent_id, $level, $idtosearch)
{
global $data, $index;
$parent_id = $parent_id === NULL ? "NULL" : $parent_id;
print_r($data);
if (isset($index[$parent_id])) {
foreach ($index[$parent_id] as $id) {
$current_id = $data[$id]["id"];
if($current_id == $idtosearch) {
$levell = $level + 1;
return $levell;
}
findNodeLevel($_SESSION['id'], $level + 1, $idtosearch);
}
}
}
This is the result:
Result of the function
The array data displayed in the 2nd image is the $data array.
The while loop:
$result = $conn->query("SELECT id, email, tipoutente, fullname, datainserimento FROM utenti WHERE inseritoda = " . $_SESSION['id']);
while($row = mysqli_fetch_array($result)){
echo "<tr class=\"righe\">";
if($row['tipoutente'] == "GRUPPO PRIVATO" || $row['tipoutente'] == "GRUPPO NEGOZI" || $row['tipoutente'] == "GRUPPO ASSOCIAZIONI") {
$livello = findNodeLevel($_SESSION['id'], 0, $row['id']);
echo "<td class=\"gruppi\">$progressivoutenti</td>";
echo "<td class=\"gruppi\">" . $row['id'] . "</td>";
echo "<td class=\"gruppi\">" . $row['fullname'] . "</td>";
echo "<td class=\"gruppi\">" . $row['email'] . "</td>";
echo "<td class=\"gruppi\">" . $row['tipoutente'] . "</td>";
echo "<td class=\"gruppi\">" . $row['datainserimento'] . "</td>";
//echo "<td class=\"gruppi\">" . $row['datadiff'] . "</td>";
echo "<td class=\"gruppi\">" . $livello . "</td>";
} else {
$livello = findNodeLevel($_SESSION['id'], 0, $row['id']);
echo "<td class=\"dati\">$progressivoutenti</td>";
echo "<td class=\"dati\">" . $row['id'] . "</td>";
echo "<td class=\"dati\">" . $row['fullname'] . "</td>";
echo "<td class=\"dati\">" . $row['email'] . "</td>";
echo "<td class=\"dati\">" . $row['tipoutente'] . "</td>";
echo "<td class=\"dati\">" . $row['datainserimento'] . "</td>";
//echo "<td class=\"dati\">" . $row['datadiff'] . "</td>";
echo "<td class=\"dati\">" . $livello . "</td>";
}
$progressivoutenti++;
echo "</tr>";
}
echo "</table>";
Inside the recursive function, when you call it again, aren't you passing the wrong parameter for parent_id ?
function findNodeLevel($parent_id, $level, $idtosearch)
{
global $data, $index;
$parent_id = $parent_id === NULL ? "NULL" : $parent_id;
print_r($data);
if (isset($index[$parent_id])) {
foreach ($index[$parent_id] as $id) {
$current_id = $data[$id]["id"];
if($current_id == $idtosearch) {
$levell = $level + 1;
return $levell;
}
findNodeLevel($current_id, $level + 1, $idtosearch);
}
}
}

rowCount based on row value

So I am trying to do this..
$userID = $_SESSION['user_session'];
$stmt = $this->db->prepare("SELECT * FROM orrs");
$stmt->bindparam(":id", $userID);
$stmt->execute();
$count = $stmt->rowCount();
echo
"<div class='table-responsive'>
<table class='table' border='1'>
<tr class='head'>
<h3>Snapshot</h3>
<th>Se</th>
<th>#s</th>
<th>Ae</th>
<th>Prt</th>
<th>Pin</th>
</tr>";
while($userRows=$stmt->fetch(PDO::FETCH_ASSOC)) {
if($userRows['stage'] == '1')
{
echo "<tr>";
echo "<td>" . "Newn" . "</td>";
echo "<td>" . $count . "</td>";
echo "<td>" . $userRows['aow'] . "</td>";
echo "<td>" . $userRows['pit'] . "</td>";
echo "<td>" . $userRows['pgin'] . "</td>";
}
else if($userRows['stage'] == '2')
{
echo "<tr>";
echo "<td>" . "Pendinn" . "</td>";
echo "<td>" . $count . "</td>";
echo "<td>" . $userRows['gfh'] . "</td>";
echo "<td>" . $userRows['pt'] . "</td>";
echo "<td>" . $userRows[trin'] . "</td>";
}
}
Basically, If the value in the row STAGE = 1 I want it to count those rows and give me the number.. If the value of STAGE = 2 I want it to count those rows and give me the number.
Right now, It is just counting all of the rows.. So for both of the IF statment its count number is saying 2, When there is only 1 in each section..
I think you need to execute three different statements, one to get all the rows (for you to loop over and create your output) and one to get each of the counts
//The current one
$stmt = $this->db->prepare("SELECT * FROM orrs");
//The get the count for stage '1'
$stage_1_stmt = $this->db->prepare("SELECT * FROM orrs where STAGE = 1");
$stage_1_count = $stage_1_stmt->rowCount();
//The get the count for stage '2'
$stage_2_stmt = $this->db->prepare("SELECT * FROM orrs where STAGE = 2");
$stage_2_count = $stage_2_stmt->rowCount();
You can execute these others to get the counts which you should use in place of $count in your loop.
Your while loop then becomes
while($userRows=$stmt->fetch(PDO::FETCH_ASSOC)) {
if($userRows['stage'] == '1')
{
echo "<tr>";
echo "<td>" . "Newn" . "</td>";
echo "<td>" . $stage_1_count . "</td>";
echo "<td>" . $userRows['aow'] . "</td>";
echo "<td>" . $userRows['pit'] . "</td>";
echo "<td>" . $userRows['pgin'] . "</td>";
}
else if($userRows['stage'] == '2')
{
echo "<tr>";
echo "<td>" . "Pendinn" . "</td>";
echo "<td>" . $stage_2_count . "</td>";
echo "<td>" . $userRows['gfh'] . "</td>";
echo "<td>" . $userRows['pt'] . "</td>";
echo "<td>" . $userRows[trin'] . "</td>";
}
}

PHP - Table id the same

How can I put identical columns (sorted by "level" in this case) together? I am making a highscore where I list them by level from my database. I want them to have the same ID if they are the same level.
But I do not want to display the ID on the others. Only the first one.
Here is an example:
ID - Name - Level
1 - John - 5
2 - David - 4
3 - Josh - 3
- Sam - 3
4 - George - 2
So I want to put them together, but if they have the same level, only the first one displays the ID.
I don't want it to look like:
1 - John - 5
2 - David - 4
3 - Josh - 3
3 - Sam - 3
4 - George - 2
Right now, it is just listing everyone, and giving each one a unique ID. Even if they have the same "level".
How can I fix this? Here is my code:
<?php
$sql = mysql_query("SELECT * FROM rookstayers ORDER BY level DESC LIMIT 0, 500");
$id = 1;
while($row = mysql_fetch_array($sql)){
$name = $row['name'];
$level = $row['level'];
$world = $row['world'];
$account = $row['accountstatus'];
$status = $row['onlinestatus'];
$onrow = '';
$typeServ = '';
$player_name = urlencode($name);
if ($status == 1){
$status = 'Online';
$onrow = 'online';
} else {
$status = 'Offline';
$onrow = 'offline';
}
if ($account == 'Premium Account'){
$account = 'Premium';
} else {
$account = 'Free';
}
if ($world == 'Aurora' || $world == 'Aurera'){
$typeServ = 'active';
} else {
$typeServ = '';
}
echo "<tr class=" . $typeServ . ">";
echo "<td>" . $id . "</td>";
echo "<td>" . $name . " <a href='http://www.tibia.com/community/?subtopic=characters&name=" . $player_name . "' target='_blank'><img src='../../img/websites/tibia.png' title='Tibia Profile'></a><a href='http://www.pskonejott.com/otc_display.php?character=" . $player_name . "' target='_blank'><img src='../../img/websites/pskonejott.png' title='Pskonejott'></a>" . "</td>";
echo "<td>" . $level . "</td>";
echo "<td>" . $world . "</td>";
echo "<td>" . $account . "</td>";
echo "<td class=" . $onrow . ">" . $status . "</td>";
echo "</tr>";
$id++;
}
echo "</tbody>";
echo "</table>";
?>
you can create a temporary variable for the current level and check it to see if the id will be shown on the output or not.
$id = 1;
$last_player_lvl = '';
while($row = mysql_fetch_array($sql)){
///....
echo "<tr class=" . $typeServ . ">";
echo "<td>" . ( ($last_player_lvl == $row['level']) ? '' : $id ) . "</td>";
echo "<td>" . $name . " <a href='http://www.tibia.com/community/?subtopic=characters&name=" . $player_name . "' target='_blank'><img src='../../img/websites/tibia.png' title='Tibia Profile'></a><a href='http://www.pskonejott.com/otc_display.php?character=" . $player_name . "' target='_blank'><img src='../../img/websites/pskonejott.png' title='Pskonejott'></a>" . "</td>";
echo "<td>" . $level . "</td>";
echo "<td>" . $world . "</td>";
echo "<td>" . $account . "</td>";
echo "<td class=" . $onrow . ">" . $status . "</td>";
echo "</tr>";
if($last_player_lvl == $row['level']){
$id = $id;
}else{
$id++;
}
$last_player_lvl = $row['level'];
//....

Find last value of array in foreach cicle

I've data stored in a array ($rows).
For read the array and genarate a dinamic table I use foreach function.
<table>
foreach ($rows as $row) {
echo "<tr>";
echo "<td>" . $row['field1'] . "</td>";
echo "<td>" . $row['field2'] . "</td>";
echo "<td>" . $row['filed3'] . "</td>";
echo "</tr>";
}
</table>
My goal is to find the last value of the array (the end) in order to change the class of TR element for the last line displayed.
How could I do this?
Thanks
Try this:
foreach ($rows as $key => $row) {
$end = end($rows) === $row ? 'class="last"' : '';
echo "<tr $end>";
echo "<td>" . $row['field1'] . "</td>";
echo "<td>" . $row['field2'] . "</td>";
echo "<td>" . $row['filed3'] . "</td>";
echo "</tr>";
}
This method works for multidimentional arrays as well.
http://codepad.org/HQG9ytBX
Edit. As pointed in comments, this approach may potentially trigger false end result if some values in the array are duplicated (with the last). Correct bullet-proof version should be:
foreach ($rows as $key => $row) {
$end = end($rows) === $row && $key === key($rows) ? 'class="last"' : '';
// ...
foreach ($rows as $row) {
$is_last_row = ++$i == count($rows);
echo "<tr>";
echo "<td>" . $row['field1'] . "</td>";
echo "<td>" . $row['field2'] . "</td>";
echo "<td>" . $row['filed3'] . "</td>";
echo "</tr>";
}
here $i should be an unused variable.
Try This
$numItems = count($rows);
$i = 0;
foreach($rows as $row) {
$trClass = 'firstclass';
if(++$i === $numItems)
{
$trClass = 'lastclass';
}
echo "<tr class='$trclass'>";
echo "<td>" . $row['field1'] . "</td>";
echo "<td>" . $row['field2'] . "</td>";
echo "<td>" . $row['filed3'] . "</td>";
echo "</tr>";
}
// first, let's find out the last key
end($rows);
$last = key($rows);
// then just loop over
foreach ($rows as $key => $row) {
if ($key == $last) {
// last leaf of the summer...
}
echo "<tr>";
echo "<td>" . $row['field1'] . "</td>";
echo "<td>" . $row['field2'] . "</td>";
echo "<td>" . $row['filed3'] . "</td>";
echo "</tr>";
}

MySQL not pulling all rows

Hey guys, first time using stackoverflow.
can you guys help me debug?
Heres the problem, this query is selecting all of the rows from my database, its only outputting the first one twice for some reason.
$top10_query = "SELECT * FROM kicks";
$result = mysqli_query($cxn, $top10_query) or die("Couldn't execute query.");
$row = mysqli_fetch_assoc($result);
$rating = $row['rating'];
$description = $row['description'];
$completed = $row['completed'];
$userid = $row['userid'];
$posted = $row['posted'];
while($row = mysqli_fetch_assoc($result)) {
echo "<tr>";
echo "<td class='rating'>" . $rating . "</td>";
echo "<td class='description'>" . $description . " </td>";
echo "<td class='completed_" . $completed . "'>" . $completed . "</td>";
echo "<td class='author'>";
echo "Posted by: <a href='profile?userid=" . $userid . "'>" . $userid . "</a><br />";
echo "on "; echo $posted;
echo "</td>";
echo "</tr>";
}
You are looping over the rowset, but never retrieving its value more than once. You pulled all of the values out of the first row, and cached them here:
$rating = $row['rating'];
$description = $row['description'];
$completed = $row['completed'];
$userid = $row['userid'];
$posted = $row['posted'];
Move this code into the loop, and remove the first fetch.
You need to update $rating, $description, etc. within the while loop:
<?php
$top10_query = "SELECT * FROM kicks";
$result = mysqli_query($cxn, $top10_query) or die("Couldn't execute query.");
while($row = mysqli_fetch_assoc($result)) {
$rating = $row['rating'];
$description = $row['description'];
$completed = $row['completed'];
$userid = $row['userid'];
$posted = $row['posted'];
echo "<tr>";
echo "<td class='rating'>" . $rating . "</td>";
echo "<td class='description'>" . $description . " </td>";
echo "<td class='completed_" . $completed . "'>" . $completed . "</td>";
echo "<td class='author'>";
echo "Posted by: <a href='profile?userid=" . $userid . "'>" . $userid . "</a><br />";
echo "on "; echo $posted;
echo "</td>";
echo "</tr>";
}
?>
Or, of course, you can inline $rating, etc., writing $row['rating'] instead.
Note: you probably want to run your variables through htmlspecialchars before inserting them into HTML. Otherwise, a description like <script>alert('hacked');</script> could execute a script, opening yourself up to XSS attacks.
You can also use extract. I do not recommend you do this, however, as it may cause problems and confusion for other developers:
<?php
$top10_query = "SELECT * FROM kicks";
$result = mysqli_query($cxn, $top10_query) or die("Couldn't execute query.");
while($row = mysqli_fetch_assoc($result)) {
extract($row);
echo "<tr>";
echo "<td class='rating'>" . $rating . "</td>";
echo "<td class='description'>" . $description . " </td>";
echo "<td class='completed_" . $completed . "'>" . $completed . "</td>";
echo "<td class='author'>";
echo "Posted by: <a href='profile?userid=" . $userid . "'>" . $userid . "</a><br />";
echo "on "; echo $posted;
echo "</td>";
echo "</tr>";
}
?>
The variables $rating etc are not "binded" to the expressions $row['rating'] etc. Once set, They will forever take these values unless you modify them again.
See PHP: Assignment Operators for detail.
Try to rewrite them as:
$top10_query = "SELECT * FROM kicks";
$result = mysqli_query($cxn, $top10_query) or die("Couldn't execute query.");
while($row = mysqli_fetch_assoc($result)) {
$rating = $row['rating']; // <-- use the new value every time a row is fetched.
$description = $row['description'];
$completed = $row['completed'];
$userid = $row['userid'];
$posted = $row['posted'];
echo "<tr>";
echo "<td class='rating'>" . $rating . "</td>";
echo "<td class='description'>" . $description . " </td>";
echo "<td class='completed_" . $completed . "'>" . $completed . "</td>";
echo "<td class='author'>";
echo "Posted by: <a href='profile?userid=" . $userid . "'>" . $userid . "</a><br />";
echo "on "; echo $posted;
echo "</td>";
echo "</tr>";
}

Categories