PHP/MySQL nested fetch? - php

I am in the process of making a quick PHP based forum, and each post in a forum will appear under its "parent" post, but slightly more indented.
To get all the posts in that order, I have the following function:
private function getData($pid, $offset)
{
$sql = 'SELECT id, subject, date
FROM post
WHERE forum_id = ? AND parent_id = ?';
$sth = $this->db->prepare($sql);
$sth->bind_param("ii", $this->id, $pid);
$sth->bind_result($id, $subject, $date);
$sth->execute();
$data = array();
while ( $sth->fetch() )
{
$row['id'] = $id;
$row['subject'] = $subject;
$row['date'] = $date;
$row['offset'] = $offset;
//Add this 'parent' post to the data array
$data[] = $row;
//Before moving on to next post, get all its children
$data[] = $this->getData($id, $offset+1);
}
$sth->close();
return $data;
}
This isn't working because I am executing another query before closing and fetching all the data from my current statement handler.
Is there a way to maybe separate the queries so they don't conflict with each other? Or any other way to by-pass this? Or will I simply have to restructure how I get my data?

Fetch all the rows into an array, then loop over them.
$rows = array();
while ( $sth->fetch() ) {
$row['id'] = $id;
$row['subject'] = $subject;
$row['date'] = $date;
$row['offset'] = $offset;
// the cool way is $rows[] = compact('id', 'subject', 'date', 'offset');
$rows[] = $row;
}
$sth->close();
foreach ($rows as $row) {
//Add this 'parent' post to the data array
$data[] = $row;
//Before moving on to next post, get all its children
$data[] = $this->getData($id, $row['offset'] + 1);
}

I will give you a example to show how to do this, this is the table i will use for the example (after just add the forum_id):
CREATE TABLE msgs (
id INT NOT NULL AUTO_INCREMENT,
date DATETIME,
name VARCHAR(100),
message TEXT,
parent_id INT NOT NULL DEFAULT 0
);
Then, with one query do:
$query = mysql_query("SELECT * FROM msgs ORDER BY id");
Some arrays to build the "posts tree", all parent_id = 0 will be root posts:
$all_messages = array(); // Will store all messages
$root_messages = array(); // Will store only the root (or more than one if you allow)
while($row=mysql_fetch_assoc($query)){ // Main loop
$all_messages[$row['id']] = array(
'inner_messages'=>array(),
'date'=> $row['date'],
'name'=> $row['name'],
'message'=>$row['message'],
'id'=>$row['id']
);
if($row['parent_id']=='0'){ // If is a root post
$root_messages[] = &$all_messages[$row['id']];
}else{ // If not a root post, places within parent message
$all_messages[$row['parent_id']]['inner_messages'][] = &$all_messages[$row['id']];
}
}
Now to print, use a recursion:
function writeTree($msgs){
foreach($msgs as $m){
echo '<div>';
echo '<h2>'.$m['name'].' ('.$m['date'].')</h2>';
echo '<div class="text">'.$m['message'].'</div>';
writeTree($m['inner_messages']);
echo '</div>';
}
}
writeTree($root_messages);

Related

Append values to its respected array PHP

I have my response where I want to fill below.
$response = array(
"year" => array(),
"playerName" => array(),
"cardVariation" => array()
);
I have a simple query to my table.
$sql = "SELECT * from $TBL";
$result = $conn->query($sql);
I will then lop through my results.
while($row = $result->fetch_assoc()) {
$year = $row['year'];
$playerName = $row['name'];
$cardVariation = $row['cardV'];
// add to response
$response['year'] = $year;
$response['name'] = $playerName;
$response['cardV'] = $cardVariation;
}
echo json_encode($response);
Expected response:
{"year": ["1999", "2000"], "name": ["bill", "jess"], "cardV": ["base","silver"]}
Only the last one gets added. I couldn't find an "append" method for PHP, unless i looked over it.
You are over writing the values each time round the loop so place the values into a new occurance each time by using $response['year'][] = . Also you are wasting time moving values into scalar variables.
while($row = $result->fetch_assoc()) {
// add to response
$response['year'][] = $row['year'];
$response['name'][] = $row['name'];
$response['cardV'][] = $row['cardV'];
}
You can use array_push() or just
$response['year'][] = $year;
$response['name'][] = $playerName;
$response['cardV'][] = $cardVariation;
https://www.php.net/manual/de/function.array-push.php

code is returning data of one date only whereas i want data of every date

function practise()
{
$this->load->database();
$qry = mysql_query("select * from demmo");
if (mysql_num_rows($qry) > 0)
{
while ($row = mysql_fetch_array($qry))
{
$created = $row['created'];
//from here
$qry = mysql_query("select * from demmo where created = '$created'");
while ($res = mysql_fetch_array($qry))
{
$user_id = $res['id'];
$name = $res['name'];
$created2 = $res['created'];
$users[] = array('user_id' => $user_id, 'name' => $name);
}
$dotts[] = array('created' => $created2);
//till here
}
return array ($dotts,$users);
}
}
in demmo table i am trying to fetch data and showing that data according to date .the problem is that the code is only selecting one date from the table from created rows and showing that data only .fortunately data shown is not only last but the data with actual date.
You need to create an array and use array_push to get more than one result. Right now your code is only returning the last result of the while loop:
For example, to get all of the dates:
$dotts = array();
$allusers = array();
while ($res = mysql_fetch_array($qry))
{
$user_id = $res['id'];
$name = $res['name'];
$created2 = $res['created'];
array_push($dotts, $created2);
$users[] = array('user_id' => $user_id, 'name' => $name);
array_push($allusers, $users);
}
//
return array ($dotts,$allusers);
You need to create an array and use array_push function , then only it will have more than one value.
example:
create an empty array as
$allUser = array();
then after this line
$users[] = array('user_id' => $user_id, 'name' => $name);
use array_push as
array_push($allUser, $users);
}
return array($dots, $allUser);

html php echo on div

here i have a simple function but this show me data fom sql only in 1 div i want to show [ on div 1 show 1 data, in other div show 2 data, etc etc]...
function load_post($added_by)
{
global $Connection;
$SQL_3 = mysqli_query($Connection, "SELECT * FROM posts WHERE added_by='$added_by'");
$NumPosts = mysqli_num_rows($SQL_3);
$out['num_posts'] = $NumPosts;
while($Fetch_3 = mysqli_fetch_array($SQL_3))
{
$out['id'] = $Fetch_3['id'];
$out['text'] = $Fetch_3['text'];
$out['added_by'] = $Fetch_3['added_by'];
$out['mp4'] = $Fetch_3['mp4'];
$out['likes'] = $Fetch_3['likes'];
$out['youtube'] = $Fetch_3['youtube'];
$out['image'] = $Fetch_3['image'];
$out['date_added'] = $Fetch_3['date_added'];
return $out;
}
}
index.php.
$posts = load_post('gentritabazi');
<div class="settings_forms_content">
<?php echo $posts['text']; ?>
</div>
return finish immediately your function so only one iteration is done. You need to save your results in array and then after loop return that array, sth like this:
$out = array();
while($Fetch_3 = mysqli_fetch_array($SQL_3))
{
$out[] = $Fetch_3;
}
return $out;
and display:
$posts = load_post('gentritabazi');
foreach ($posts as $post) {
echo '<div class="settings_forms_content">';
echo $post['text'];
echo '</div>';
}
Lots to amend, so I commented the code rather than write an essay
function load_post($con, $added_by)
{
// dont use globals, use parameters
//global $Connection;
// select only what you want to see not `*`
$SQL_3 = mysqli_query($con, "SELECT id, text, added_by, mp4,
likes, youtube, image, data_added
FROM posts
WHERE added_by='$added_by'");
// not needed
//$NumPosts = mysqli_num_rows($SQL_3);
//$out['num_posts'] = $NumPosts;
while($Fetch_3 = mysqli_fetch_array($SQL_3))
{
/*
* THsi code would overwrite the last iteration of the while loop
$out['id'] = $Fetch_3['id'];
$out['text'] = $Fetch_3['text'];
$out['added_by'] = $Fetch_3['added_by'];
$out['mp4'] = $Fetch_3['mp4'];
$out['likes'] = $Fetch_3['likes'];
$out['youtube'] = $Fetch_3['youtube'];
$out['image'] = $Fetch_3['image'];
$out['date_added'] = $Fetch_3['date_added'];
*/
// now as you SELECT only what you want yo can simply do
$out[] = $Fetch_3;
//return $out; instantly terminates the function
}
return $out; // return the array
}
Now call your function
// pass the connection as a parameter
$posts = load_post($Connection, 'gentritabazi');
// if you want to know how many results were returned
$result_count = count($posts);
// process the returned array
foreach ( $posts as $post ) {
echo '<div class="settings_forms_content">';
echo $post['text'];
echo '</div>';
}
Your script is at risk of SQL Injection Attack
Have a look at what happened to Little Bobby Tables Even
if you are escaping inputs, its not safe!
Use prepared statement and parameterized statements
$posts = load_post('gentritabazi');
foreach ($posts ['text'] as $postText){
echo "<div class='settings_forms_content'>$postText</div>";
}
first line calls your function which returns the array $posts
this array looks like:
$posts = array(
"id" => array of ids
"text" => array of texts
...
);
if you want to access the third text it would be like this:
$posts ['text'][3]
the foreach iterates to your $post array with index "text" -> which is also an array
every value in this array, $post['text'] will be referenced with $postText -> that means:
$post['text'][1] = $postText (first time looping through foreach-loop)
$post['text'][2] = $postText (secondtime looping through foreach-loop)
..
if you are familiar with loops, a foreach is just the short version for
for(var $i=0;$i<length($posts['text'];$i++){
echo "<div class='settings_forms_content'>$posts['text'][i]</div>";
}

php for each in while loop

I am trying to get specific data from a while loop and loop it x number of times.
I'm selecting this data:
$r=mysql_query("SELECT ac6, ac5, ac4, ac3, ac2, ac1, ac0 FROM advertisements WHERE token = '".$_GET['token']."'");
while ($adData = mysql_fetch_array($r, MYSQL_NUM))
{
$data = $adData;
$ac0 = $data['ac0'];
$ac1 = $data['ac0'];
print $ac0;
print $ac1;
}
This doesn't work. Nothing gets printed out.
What I want to do is to get ac6 to ac0 value for that specific advertisement (where token).
How can I do that?
Change your numeric fetch to an associative one, then add a foreach loop to process the result.
$r = mysql_query("SELECT ac6, ac5, ac4, ac3, ac2, ac1, ac0
FROM advertisements WHERE token = '" . $_GET['token'] . "'");
while ($adData = mysql_fetch_assoc($r))
{
foreach ($adData as $key => $value)
{
$nubmer = (int)substr($key, 2);
print $value; // or whatever you actually want to do
}
}
Also I hope you're validating $_GET['token'] against possible mischief in your code.
You can create an arrays to add the values from the result query
1st is to create an array:
$advert_AC0 = array();
$advert_AC1 = array();
$advert_AC2 = array();
$advert_AC3 = array();
$advert_AC4 = array();
$advert_AC5 = array();
$advert_AC6 = array();
Now, to add content to array
$r = mysql_query("SELECT ac6, ac5, ac4, ac3, ac2, ac1, ac0
FROM advertisements WHERE token = '" . $_GET['token'] . "'");
if(mysql_num_rows($r)){ //check 1st if there is num of rows from the result
while ($adData = mysql_fetch_assoc($r))
{
array_push($advert_AC0, $dData['ac0']);
array_push($advert_AC1, $dData['ac1']);
array_push($advert_AC2, $dData['ac2']);
array_push($advert_AC3, $dData['ac3']);
array_push($advert_AC4, $dData['ac4']);
array_push($advert_AC5, $dData['ac5']);
array_push($advert_AC6, $dData['ac6']);
}
}else{
echo "NO RESULT.";
}
to call for the array values, 1 by 1
$count_array = count($advert_AC0);
$i = $count_array;
while(1 <= $i){
echo "AC0: $advert_AC0[$i]<br>";
echo "AC1: $advert_AC1[$i]<br>";
echo "AC2: $advert_AC2[$i]<br>";
echo "AC3: $advert_AC3[$i]<br>";
echo "AC4: $advert_AC4[$i]<br>";
echo "AC5: $advert_AC5[$i]<br>";
echo "AC6: $advert_AC6[$i]<br>";
$i++;
}
I don't know if my answer solved your question, please comment if not.

Searching Array in PHP and return results

Can't find quite the right answer so hope someone can help. Basically want to create an array and then return the results from a search e.g.
$tsql = "SELECT date, staffid, ID,status, eventid, auditid from maincalendar";
$params = array();
$options = array( "Scrollable" => SQLSRV_CURSOR_KEYSET );
$stmt = sqlsrv_query( $conn, $tsql , $params, $options);
$calarray=array();
while($row = sqlsrv_fetch_array($stmt)) {
$rowresult = array();
$rowresult["status"] = $row['status'];
$rowresult["eventid"] = $row['eventid'];
$rowresult["caldate"] = $row['date'];
$rowresult["staffid"] = $row['staffid'];
$rowresult["ID"] = $row['ID'];
$rowresult["auditid"] = $row['auditid'];
$calarray[] = $rowresult;
}
I would then like to search for values matching 'caldate' and 'staffid' and return the associated entry in $calarray
I suggest the following,
Fetch all data needed for the current month you are showing, using col BETWEEN x AND y
Add them to a array in PHP, with staffid and caldate as key
Something like so;
$calarray[$row['staffid'] . '-' . $row['date']][] = $row;
Not sure if a single staffid/date combination can have one or more events per day, if not you can remove the []
To check if we have information for a specific staffid/date combination, use isset
if (isset($calarray[$staffid . '-' . $mydate]) { ... }
Add indexes to the fields you're going to query, and then move the search to the sql query. You can also make simple filtering inside the loop. So you'll be populating several arrays instead of one, based on the search you need.
try this:
$matches = array();
$caldate = //your desired date;
$staffid = //your desired id;
foreach($calarray as $k => $v){
if(in_array($caldate, $v['caldate']) && in_array($staffid, $v['staffid'])){
$matches[] = $calarray[$k];
}
}
$matches should be and array with all the results you wanted.
also:
while($row = sqlsrv_fetch_array($stmt)) {
$rowresult = array();
$rowresult["status"] = $row['status'];
$rowresult["eventid"] = $row['eventid'];
$rowresult["caldate"] = $row['date'];
$rowresult["staffid"] = $row['staffid'];
$rowresult["ID"] = $row['ID'];
$rowresult["auditid"] = $row['auditid'];
$calarray[] = $rowresult;
}
can be shortened into:
while($row = sqlsrv_fetch_array($stmt)) {
$calarray[] = $row;
}
Maybe this code snipplet solves your problem.
I am not a PHP programmer, so no warrenty.
function searchInArray($array, $keyword) {
for($i=0;$i<array.length();$i++) {
if(stristr($array[$i], $keyword) === FALSE) {
return "Found ".$keyword." in array[".$i."]";
}
}
}

Categories