I am sorry for my lazy title. I hope that a moderator could improve it so the database won't get infected.
I got the following code (forum.php);
<?php
$res = $db->query('
SELECT *
FROM forums_categories
ORDER BY category_id
');
while ($row = $db->fetch_array($res)) {
$categories = array(
'ID' => $row['category_id'],
'NAME' => $row['category_name']
);
echo '<pre>';
print_r($categories);
echo '</pre>';
}
And I got the following database structure;
|---------------|-------------------|
| category_id | category_name |
|---------------|-------------------|
| 1 | Example 1 |
| 2 | Example 2 |
| 3 | Example 3 |
| 4 | Example 4 |
| 5 | Example 5 |
| 6 | Example 6 |
|---------------|-------------------|
But my array only returns 1 value:
Array
(
[ID] => 1
[NAME] => Example 1
)
Oh and if somebody likes to know how my $db->fetch_array looks like:
<?php
function fetch_array($result)
{
return mysql_fetch_assoc($result);
}
How can I return all rows in my array? Thank you for reading and thank you for replying!
You're overwriting the previous value of $categories on each iteration
$categories[] = array(
'ID' => $row['category_id'],
'NAME' => $row['category_name']
);
You might also want to initialize an empty array
$categories = array();
before your loop to avoid warnings.
Related
At the moment I have a database structure like so:
| id | name | parent_id
| 1 | Human Resources | 0
| 2 | Marketing | 0
| 3 | Operations | 0
| 4 | Design | 0
| 5 | Marketing Design| 4
| 6 | Graphic Design | 4
| 7 | Print Design | 4
| 8 | Human Personal | 1
| 9 | Food Ops | 3
As you can see these are the departments within the business and also sub departments.
A sub-departments parent_id is the id of the department
do, for example:
id: 4, name: Design, parent_id: 0
id: 7, Print Design, parent_id: 4
Print Design is a sub department of design
I have called everything from the database in one query and now I need them in this structure:
$depts = array(
"Human Resources" => array("Human Personal"),
"Marketing" => array(),
"Operations" => array("Food Ops"),
"Design" => array("Marketing Design", "Graphic Design", "Print Design"),
...
);
so far I have:
foreach ($results as $result) {
if ($result['parent_id'] == 0) {
$parentCategories_arr[array($result['id'] => $result['name'])];
} else {
$returnedResults_arr[$result['parent_id']] = array($result['name']);
}
}
However I completely think that I have missed the point. so my question:
How do I loop through all the contents of that results and add the parent categories into an array with their sub categories as an array?
Maybe there is an easier way, but it works : (hate to say that sentence) - try to make it better maybe
$mFinalArray = fixMyArray($results);
print_r($mFinalArray);
function fixMyArray($results){
// Create categories - parent_id == 0
foreach($results as $index => $result) // $index = 0|1|2|3|4|5|6|7|8|9
if($result['parent_id'] == 0) // $result['parent_id'] = current item parent_id
$mCategories[$result['name']] = $result['id']; // $mCategories['Human Resources'] = 1|2|3|4
// Insert each data to the right parent
foreach($results as $index => $result) // $index = 0|1|2|3|4|5|6|7|8
if($result['parent_id'] != 0)
foreach($mCategories as $subindex => $category) // $subindex = Human Resources | Marketing | Operations | Design
if($result['parent_id'] == $category) // $category = 0|1|2|3|4
$mFinalArray[$subindex][] = $result['name']; // ex. $mFinalArray['Human Resources'][] = Human Personal
return $mFinalArray;
}
*Last line has an extra [ ] $mFinalArray[$subindex][ ]= $result['name'] . That means append to array.
Output :
Array
(
[Design] => Array
(
[0] => Marketing Design
[1] => Graphic Design
[2] => Print Design
)
[Human Resources] => Array
(
[0] => Human Personal
)
[Operations] => Array
(
[0] => Food Ops
)
)
I am developing a website using laravel PHP and trying to do a comment system using the following structure:
- Comment 1 (id = 1)
-- Reply 1 (id = 2) (parent_id = 1)
--- Reply 2.1 (id = 3) (parent_id = 2)
-- Reply 2 (id = 4) (parent_id = 1)
I am wondering how would I do a foreach to cover that? Since i don't know how many child comments a comment will have.
I wouldn’t store comments and replies in a separate table as they’re both comment entities at the end of the day. Simply have a parent_id column in your comments table, and you can fetch both comments and replies in one database query as opposed to two.
I assume you also have a foreign key linking a comment to something like a post. You can then fetch all comments for that post ID:
$comments = Comment::latest()->where('post_id', '=', $post->id)->get();
Then sort them based on their parent_id value:
$comments = $comments->keyBy('parent_id');
You can then iterate over them in your Blade template like this and every iterate, check if there are comments with that comment’s ID as its parent ID:
<!-- Kick-start the loop -->
#foreach($comments[0] as $comment)
#include('partials.comment')
#endforeach
The content of partials/comment.blade.php
<blockquote class="comment">
<p class="comment-body">{{ $comment->body }}</p>
<footer>
<span class="comment-author">{{ $comment->user->name }}</span>,
<time class="comment-date" pubdate="pubdate">{{ $comment->created_at }}</time>
</footer>
</blockquote>
#if(isset($comments[$comment['id']])
#each('partials.comment', $comments[$comment['id'], 'comment')
#endif
Table Like:
+------------+-----------+---------+
| comment_id | parent_id | comment |
+------------+-----------+---------+
| 1 | 0 | test |
| 2 | 1 | test1 |
| 3 | 0 | test2 |
| 4 | 0 | test3 |
| 5 | 1 | test4 |
| 6 | 2 | test4 |
| 7 | 4 | test5 |
| 8 | 5 | test6 |
| 9 | 6 | test7 |
| 10 | 4 | test8 |
| 11 | 3 | test9 |
+------------+-----------+---------+
Get first level parent:
$comments = Comment::where('parent_id', '0')->orderBy('comment_id', 'asc')->get();
$result = array();
foreach($comments as $comment){
$list = array();
$list = array_merge($list, [['comment_id' => $comment->comment_id, 'parent_id' => $comment->parent_id, 'comment' => $comment->comment]]);
$result = array_merge($result, $this->get_child_comment($comment->comment_id,0, $list));
}
function get_child_comment($pid,$level,$list=array()) {
$sub_comments = Comment::where('parent_id','=',$pid)->where('comment_id','!=',$pid)->orderBy('comment_id', 'asc')->get();
foreach($sub_comments as $sub_comment){
$space=" "; sigm='-';
for($j=0; $j<=$level; $j++)
{
$space .=$space;
}
for($j=0; $j<=$level; $j++)
{
$space .= $sigm;
}
$sub_comment->comment = html_entity_decode($space, ENT_QUOTES, "utf-8").' '.$sub_comment->comment;
$list = array_merge($list, array(['comment_id' => $sub_comment->comment_id, 'parent_id' => $sub_comment->parent_id, 'comment' => $sub_comment->comment]));
$list = $this->get_child_comment($sub_comment->comment_id, $level+1, $list);
}
return $list;
}
}
return get array.simple print using foreach:
foreach($result as $val) {
echo $val['comment'].'<br>';
}
Output:
test
- test1
-- test4
--- test7
- test4
-- test6
test2
- test9
test3
- test5
- test8
You can represent comments in following structure:
$comments = [
(object)[
'id' => 1,
'text' => 'Comment 1',
'children' => [
(object)[
'id' => 2,
'text' => 'Reply 1',
'children' => [
(object)[
'id' => 2,
'text' => 'Reply 1.1'
]
]
],
(object)[
'id' => 4,
'text' => 'Reply 2',
]
]
]
];
And print them using recursive function like this:
function printComments($comments, $prefix = '-') {
foreach ($comments as $comment) {
echo $prefix.$comment->text.'<br>';
isset($comment->children) && printComments($comment->children, $prefix.'-');
}
}
Or calling view recursively in case of Laravel:
#include('comments.view.path') inside of
#include('comments.view.path')
For convinient retrieving of comments in the represented structure and generally for working with tree structure I suggest using nested set model and etrepat/baum for Laravel which has toHierarchy() method.
I have two mysql database table, one is for posts and other is for comments.
Post table
+----+-------+
| ID | texts |
+----+-------+
| 1 | abc |
| 2 | xyz |
+----+-------+
And comments table
+----+--------+-------+
| ID | postid | texts |
+----+--------+-------+
| 1 | 1 | abc1 |
| 2 | 1 | abc2 |
| 3 | 1 | abc3 |
| 4 | 2 | xyz1 |
| 5 | 2 | xyz2 |
+----+--------+-------+
Now, How to get posts with bare minimum mysql query requests, so that output is like,
$data = array(
0 => array(
ID => 1,
texts => abc,
comments => array(
0 => array(
ID => 1,
texts => abc1
)
1 => array(
ID => 2,
texts => abc2
)
2 => array(
ID => 3,
texts => abc3
)
)
)
1 => array(
ID => 2,
texts => xyz,
comments => array(
0 => array(
ID => 4,
texts => xyz1
)
1 => array(
ID => 5,
texts => xyz2
)
)
)
)
How about
SELECT *
FROM Post p LEFT JOIN
Comments c ON p.ID = c.postID
It will be helpful if you can provide code to put results in array
Let me first recommend a better multidimensional array that will be easier to work with.
Array Format:
$data = array(
post.ID => array(
"texts" => post.texts,
"comments" => array(
comments.ID => comments.texts,
),
),
);
The above format will be easier to work with especially for direct access into the array and also for the foreach loop.
Now for assigning the data from the MySQL result into the array using mysqli_* functions and a while loop do the following:
//connect to mysql database
$link = $mysqli_connect("localhost","your_user","your_password","your_database");
//form mysql query
$query = "
SELECT
post.ID AS post_id,
post.texts AS post_texts,
comments.ID AS comments_id,
comments.texts AS comments_texts
FROM
post
LEFT JOIN comments ON (comments.postid = post.ID)
WHERE
posts.ID < 10
";
//run mysql query and return results
$mysqli_result = mysqli_query($link,$query);
//define empty $data array
$data = array();
//loop through result sets fetching string array with each result row
while($row = mysqli_fetch_array($mysqli_result)){
//set the post text if not already set
if(!isset($data[$row["post_id"]]["texts"])){
$data[$row["post_id"]]["texts"] = $row["post_texts"];
}
//set the comments data if not NULL otherwise set comments to empty array to maintain structure
if(!empty($row["comments_id"])){
$data[$row["post_id"]]["comments"][$row["comments_id"]] = $row["comments_texts"];
} else {
$data[$row["post_id"]]["comments"] = array();
}
}
//free the results set
mysqli_free_result($mysqli_result);
//close connection to mysql database
mysqli_close($link);
//print out the post text with the id of 1 with two line breaks
//be careful using this method unless you are sure that post with id of 1 exists or first check if(isset($data["1"])){...}
print $data["1"]["texts"]."<br /><br />";
//loop through all of the comments for a particular post with id of 1
foreach($data["1"]["comments"] as $key => $value){
//print out the comment id with a line break
print "Comment ID: ".$key."<br />";
//print out the comments texts with two line breaks
print "Comment: ".$value."<br /><br />";
}
//loop through and print all the post texts and how many comments exist for the post
foreach($data as $key => $value){
//print the post ID with a line break
print "Post ID: ".$key."<br />";
//print the post texts with a line break
print "Post: ".$value["texts"]."<br />";
//count the number of comments
$num_comments = count($value["comments"]);
//get correct plural form of noun
($num_comments==1) ? $comments = "comment" : $comments = "comments";
//print the number of comments for the post with two line breaks
print $num_comments." ".$comments." for this post.<br /><br />";
}
I'm working on a Bubble Chart using Highcharts. Here's a sample of my data:
name | price | quantity | count
--------+-------+----------+-------
Female | 2 | 3 | 5
Female | 3 | 12 | 10
Female | 5 | 6 | 15
Female | 1 | 7 | 25
Male | 3 | 5 | 7
Male | 2 | 9 | 11
Male | 5 | 7 | 23
Male | 4 | 4 | 14
I'm using PHP to query the data and encode to JSON:
$query = "SELECT name, price, quantity, count FROM sales WHERE id = $1";
$result = pg_prepare($db, "report", $query);
$result = pg_execute($db, "report", array($ID));
while ($row = pg_fetch_array($result, NULL, PGSQL_ASSOC))
{
$response['xdata'][$row['name']]['x'][] = $row['price'];
$response['xdata'][$row['name']]['y'][] = $row['quantity'];
$response['xdata'][$row['name']]['radius'][] = $row['count'];
}
echo json_encode($response);
However, the desired JSON format is as follows in order to properly plot the graph:
series: [{
name: 'Female',
marker:{
symbol:'circle',
fillColor:'rgba(24,90,169,.5)',
lineColor:'rgba(24,90,169,.75)',
lineWidth:1,
color:'rgba(24,90,169,1)',
states:{
hover:{
enabled:false
}
}
},
data: [{x:2,y:3,marker:{radius:5}},
{x:3,y:12,marker:{radius:10}},
{x:5,y:6,marker:{radius:15}},
{x:1,y:7,marker:{radius:25}}]
},{
name: 'Male',
marker:{
symbol:'circle',
fillColor:'rgba(238,46,47,.5)',
lineColor:'rgba(238,46,47,.75)',
lineWidth:1,
color:'rgba(238,46,47,1)',
states:{
hover:{
enabled:false
}
}
},
data: [{x:3,y:5,marker:{radius:7}},
{x:2,y:9,marker:{radius:11}},
{x:5,y:7,marker:{radius:23}},
{x:4,y:4,marker:{radius:14}}]
}]
My question is, how can I correctly process $query in PHP to get the desired JSON format as above and pass it to series through something like optionsBubble.series = data.xdata? Thanks a lot!
You'd first have to build the non-db-related parts into your PHP structure, e.g.
$data = array(
0 => array(
'name' => 'Female',
'marker' => array (
'symbol': 'circle'
etc....),
'data' => array() // database insertion occurs here
),
1 => array(
'name' => 'Male',
etc...
)
);
$locations = array('Female' => 0, 'Male' => 1, etc...) // reverse map your 'name' fields
while(...) {
$data[$locations[$row['name']]][data]['x'][] = $row['price'];
$data[$locations[$row['name']]][data]['y'][] = $row['quantity'];
^^^^^^^^^^^^^^^^^^^^^^^^--- reverse lookup to get right array index for 'name'
}
First I'm going to recommend you take a look at your SQL query, especially the part of WHERE id=$1. If I'm not mistaken (and on this I'm fairly sure.) your query is going to return one (1) row not many like what you probably want. I would recommend removing the WHERE clause and see if that solves your problem.
If not drop me a line and I'll see what else I see and we can go from there.
I have a table "exercise_results". People put in their results at the beginning and then two months later put in their results to see how much they improved. Their beginning set has the exercise_type_id of "1" and the end set has the exercise_type_id of "2".
I need a way to display this out into a HTML table that looks like this:
a foreach loop, but that's with single rows. I'm having trouble combining two rows into one. I think this may be as simple as some kind of MySQL join? We identify each person by their person_unique_id.
Here are my fields:
id | person_unique_id | person_name | exercise_type_id | mile_running_time | bench_press_weight_lbs | squat_weight_lbs | date_of_exercise_performed
Sample rows:
1 | J123 | John Smith | 1 | 8 | 200 | 300 | 2010-03-20
2 | J123 | John Smith | 2 | 7 | 250 | 400 | 2010-05-20
3 | X584 | Jane Doe | 1 | 10 | 100 | 200 | 2010-03-20
4 | X584 | Jane Doe | 2 | 8 | 150 | 220 | 2010-05-20
I've tried a few solutions but I'm lost. Any help would be great. Thanks!
EDIT:
In response to the comment below, I would hope for some data like:
array 0 =>
array
'Exercise' =>
array
'person_unique_id' => string 'J123'
'person_name' => string 'John Smith'
'begin_mile_running_time' => string '8'
'end_mile_running_time' => string '7'
1 =>
array
'Exercise' =>
array
'person_unique_id' => string 'X584'
'person_name' => string 'Jane Doe'
'begin_mile_running_time' => string '10'
'end_mile_running_time' => string '8'
You can use GROUP_CONCAT() to get a two rows result like this:
SELECT person_unique_id, person_name,
group_concat( mile_running_time ) AS miles,
group_concat( bench_press_weight_lbs ) AS bench,
GROUP_CONCAT( squat_weight_lbs ) AS squat
FROM exercise_result
GROUP BY person_unique_id
Your result will be like:
J123 | John Smith | 8,7 | 200,250 | 300,400
X584 | Jane Doe | 10,8 | 100,150 | 200,220
And then you can use php explode with the result fields to get the results for each type.
Extract the whole table, or whichever rows are interesting to you, sort on person id, compare person id of each row with the next to see if there is a result to print for all columns in your HTML table. If not, jump to the next and leave the fields blank(or some other solution, maybe ignore persons who have not filled in both fields?).
My PHP skills are limited, so no code example.
$query = mysql_query("select ...your data");
while ($row = mysql_fetch_assoc ($query) ) {
if ($row['exercise_type_id']==1)
$exe1[]=$row;
else
$exe2[]=$row;
}
print_r($exe1);
print_r($exe2);
from what I've understood
edit:
try this
$query = mysql_query("select ...your data");
while ($row = mysql_fetch_assoc ($query) ) {
$rows[]=array('Exercise'=>$row);
}
print_r($rows);
If you are ordering on person_unique_id then exercise_type_id, you can do this. If you have two rows for everyone, you can leave out the if (only use the else):
for( $i = 0; $i < count($exercise_results); $i++ )
{
$first = $exercise_results[$i];
if( !isset($exercise_results[$i+1])
|| $first['person_unique_id'] != $exercise_results[$i+1]['person_unique_id' ) {
$second = array(
'person_name'=>$other['person_name'],
'mile_running_time' => null // fill in the rest with defaults (like null)
);
} else {
$second = $exercise_results[$i+1];
$i++; // skip ahead one, since you've already used the second result.
}
// perform your normal printing, but use $beginning and $end to get the respective results
}