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);
}
}
}
Related
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
<?php
$con = mysqli_connect('localhost', 'root', '');
if(!$con)
{
die("not ok");
}
mysqli_select_db($con,"uoh");
$q1 = "SELECT * FROM student_record INNER JOIN degree_plan ON
student_record.course_number = degree_plan.course_number
INNER JOIN courses ON student_record.course_number =
courses.course_number where student_record.id = 201102887 AND degree_plan.major='COE'";
$result = mysqli_query($con , $q1 ) ;
$data = array();
while($row = mysqli_fetch_array($result))
{
$data[$row["term_no"]][] = array(
'code' => $row["code"],
'grade' => $row["grade"]
);
}
echo '<table width="200" border="1">';
echo "<tr>";
echo "<th>courses</th>";
echo "<th>terms</th>";
echo "<th>grades</th>";
echo "</tr>";
foreach($data as $term=>$otherrow) {
$count = 0;
foreach ($otherrow as $data) {
if($count == 0) {
echo "<tr>";
echo "<td>" . $data["code"]. "</td>";
echo '<td rowspan="'.count($otherrow).'">' . $term. '</td>';
echo "<td>" . $data["grade"]. "</td>";
echo "</tr>";
}
else
{
echo "<tr>";
echo "<td>" . $data["code"]. "</td>";
echo "<td>" . $data["grade"]. "</td>";
echo "</tr>";
}
$count++;
}
}
echo "</table>";
?>
I have this code and it work very well but I faced problem when I want to add more column .
I tried to add fourth column(echo "<td>" . $row["crd"]. "</td>"; ) but there is no result .It give me empty cells. how I can do that?
I want add add this echo "<td>" . $row["crd"]. "</td>"; column to my code.
As mentioned in the comments, there are two errors that have been noticed.
You are re-declaring $data in your second foreach loop
You don't have $row initiated anywhere, and atempting to echo $row["crd"] will result in an empty cell.
Proposed Solution:
Change the name of the $data value in the foreach loop to $row and hence solve both problems at the same time:
foreach($data as $term=>$otherrow) {
$count = 0;
foreach ($otherrow as $row) {
if($count == 0) {
echo "<tr>";
echo "<td>" . $row["code"]. "</td>";
echo '<td rowspan="'.count($otherrow).'">' . $term. '</td>';
echo "<td>" . $row["grade"]. "</td>";
echo "</tr>";
}
else
{
echo "<tr>";
echo "<td>" . $row["code"]. "</td>";
echo "<td>" . $row["grade"]. "</td>";
echo "</tr>";
}
$count++;
}
}
And when you add echo "<td>" . $row["crd"]. "</td>"; now it should echo the value stored in the $row array (as long as the value was extracted from the table in the database in the first place of course).
Let me know if this worked for you.
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'];
//....
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>";
}
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>";
}