PHP how to extract information from an array within an array? - php

First, I would like to mention that I'm terrible at PHP but I'm trying my best to work with it. For some reason I can get information from an array in PHP but I just can't extract information from an array within an array..
So here's the page that var_dumps the array: http://www.farahfa.com/iplanner/webservice/assign_blah.php
And I want to extract all the information in that inner array but I can't figure out how to do it..
Here's my code so far.
<?php
include_once "../config/config.php";
// Expected from the app: student_id & assignment_date
$student_id = $_POST['student_id'];
$assignment_date = $_POST['assignment_date'];
$return=[];
$sql = "SELECT DISTINCT
s1.name AS subject,
a.id AS assignmentID,
sa.id AS subjectAssignID,
sa.content AS content,
sa.due_date AS dueDate,
a.general_teacher_note AS generalNote,
sn.note_content AS specificNote,
sub.isSigned AS isSigned
FROM student AS s
LEFT JOIN enrollment AS e ON e.id = e.student_id
LEFT JOIN classroom AS c ON c.id = e.classroom_id
LEFT JOIN assignment AS a ON c.id = a.classroom_id
LEFT JOIN submission AS sub ON a.id = sub.assignment_id
LEFT JOIN specific_notes AS sn ON a.id = sn.assignment_id
LEFT JOIN subject_assignment AS sa ON a.id = sa.assignment_id
LEFT JOIN subject_class AS sc ON sc.id = sa.subject_class_id
LEFT JOIN subject AS s1 ON s1.id = sc.subject_id
WHERE e.student_id = 2 AND a.date = '2015-04-07'";
$result = $conn->query($sql); // Execute the query
if ($result->rowCount() >= 1) // If there are data returned then do the following
{
$subject_assignments = $result->fetchAll(); // Get all the rows that are returned
var_dump($subject_assignments);
for($i = 0; $i < sizeof($subject_assignments); ++$i )
{
for($j = 0; $j < sizeof($i); ++$j )
{
/*[
['subjectAssignID' => $subject_assignments[$i][$j]['subjectAssignID'],
'subject' => $subject_assignments[$i][$j]['subject'],
'content' => $subject_assignments[$i][$j]['content'],
'dueDate' => $subject_assignments[$i][$j]['dueDate']],
['subject' => $subject_assignments[$i][$j]['subject'],
'content' => $subject_assignments[$i][$j]['content'],
'dueDate' => $subject_assignments[$i][$j]['dueDate']],
['generalNote' => $subject_assignments[$i][$j]['generalNote'],
'specificNote' => $subject_assignments[$i][$j]['specificNote'],
'assignmentID' => $subject_assignments[$i][$j]['assignmentID'],
'isDone' => $subject_assignments[$i][$j]['isDone']]
]*/
}
}
}
/*
[
[
'subjectAssignID' => '1',
'subject' => 'subjectHere',
'content' => '1',
'dueDate' => 'sdfds'
],
['subject' => 'subjectHere','content' => '1','duedate' => 'sdfds'],
],
'teacherNote' => 'Whatever',
'parentNote' => 'Note Parent'
'assignmentID' => '1'
echo json_encode($return); //Makes it a json array
} else {
echo 0;
}
*/
?>
If anyone can help me with this I'd be eternally thankful!

<?php
//Lets say your $result looks something like this
$result[]= array("subjectAssignID"=> 111, "isSigned"=> "yes", "assignmentID"=>222,
"subjectName"=>"subject", "content"=>"test", "dueDate"=>"April",
"generalNote"=>"general", "specificNote"=>"specific"
);
$file = file_get_contents('json.json');
unset($file);
file_put_contents('json.json', json_encode($result));
unset($result);
Then your json file will have this
[{"subjectAssignID":111,"isSigned":"yes","assignmentID":222,"subjectName":"subject","content":"test","dueDate":"April","generalNote":"general","specificNote":"specific"}]
Hope this helps!

I'm assuming your sql commands are correct
I did not check this code but the idea is to use a nested foreach loop
<?php
include_once "../config/config.php";
// Expected from the app: student_id & assignment_date
if($_POST['student_id'] && $_POST['assignment_date'])//only except the code if those conditions are true
{
$return=[];
$sql = "SELECT DISTINCT
s1.name AS subject,
a.id AS assignmentID,
sa.id AS subjectAssignID,
sa.content AS content,
sa.due_date AS dueDate,
a.general_teacher_note AS generalNote,
sn.note_content AS specificNote,
sub.isSigned AS isSigned
FROM student AS s
LEFT JOIN enrollment AS e ON e.id = e.student_id
LEFT JOIN classroom AS c ON c.id = e.classroom_id
LEFT JOIN assignment AS a ON c.id = a.classroom_id
LEFT JOIN submission AS sub ON a.id = sub.assignment_id
LEFT JOIN specific_notes AS sn ON a.id = sn.assignment_id
LEFT JOIN subject_assignment AS sa ON a.id = sa.assignment_id
LEFT JOIN subject_class AS sc ON sc.id = sa.subject_class_id
LEFT JOIN subject AS s1 ON s1.id = sc.subject_id
WHERE e.student_id = 2 AND a.date = '2015-04-07'";
$result = $conn->query($sql); // Execute the query
if ($result->rowCount() >= 1) // If there are data returned then do the following
{
$subject_assignments = $result->fetchAll(); // Get all the rows that are returned
var_dump($subject_assignments);
foreach($subject_assinments as $subject )
{
foreach($subject as $assinment )
{
//put your code here
echo $assinment;
}
}
}
}

Related

Cannot get the proper set of data using PHP and MySQL

I need to fetch data from DB in an array using PHP and MySQL. In my case I am having 1 set of data in the given condition but the same set of data is coming multiple times. I am providing my code below.
$pro_id=$_GET['pro_id'];
$userid=$_GET['user_id'];
$sql="
SELECT s.id,
s.voucher_code,
s.merchant,
s.date,
s.receiver,
s.sender,
s.serial_no,
s.image,
s.expired_date,
s.product_id,
c.status,
c.redeem_status,
sup.supplier_id,
sup.NAME,
a.NAME AS sender_name,
v.discount,
v.discount_type,
v.voucher_amount,
p.product_name AS pro_name
FROM db_send_evoucher_code s
INNER JOIN db_code c
ON s.voucher_code = c.total_voucher_code
INNER JOIN db_supplier sup
ON s.merchant = sup.supplier_id
INNER JOIN medilink_admin a
ON s.sender = a.admin_id
INNER JOIN db_voucher_code v
ON c.voucher_code_id = v.voucher_code_id
INNER JOIN db_product_info p
ON s.product_id = p.pro_id
WHERE s.receiver = '". $userid ."'
and s.product_id = '". $pro_id ."'";
$sqlqry = mysqli_query($con, $sql);
if (mysqli_num_rows($sqlqry) > 0) {
while ($row = mysqli_fetch_array($sqlqry)) {
if ($row['discount_type'] == 'Flat') {
$distype = 1;
}
if ($row['discount_type'] == 'percentage') {
$distype = 2;
}
$data['data'][] = $data['data'][] = array("voucher_code" => $row['voucher_code'], "send_by" => $row['sender_name'], "image" => $row['image'], "expired_date" => $row['expired_date'], "supplier_name" => $row['name'], "sending_date" => $row['date'], "supplier_id" => $row['supplier_id'], "discount" => $row['discount'], "product_id" => $row['product_id'], "product_name" => $row['pro_name'], "redeem_status" => $row['redeem_status'], "voucher_amount" => $row['voucher_amount'], "discount_type" => $distype, "imagepath" => $imagepath);
echo json_encode($data, JSON_UNESCAPED_SLASHES);
}
} else {
$data['data'] = array();
echo json_encode($data);
}
Here in the given condition I have one set of data inside DB but it's coming two times. Here is my output:
{"data":[{"voucher_code":"FIFLTBH8567","send_by":"Medilink","image":"glotnzgrqbyb9_97yw155165stt9_eneoji_l.jpg","expired_date":"22-02-2016","supplier_name":"Eneoji","sending_date":"2016-02-18 16:11:35","supplier_id":"9","discount":"20","product_id":"52","product_name":"Eneoji Fomentation Therapy","redeem_status":"0","voucher_amount":"2000","discount_type":2,"imagepath":"http://li120-173.members.linode.com/crm_beta/upload/"},{"voucher_code":"FIFLTBH8567","send_by":"Medilink","image":"glotnzgrqbyb9_97yw155165stt9_eneoji_l.jpg","expired_date":"22-02-2016","supplier_name":"Eneoji","sending_date":"2016-02-18 16:11:35","supplier_id":"9","discount":"20","product_id":"52","product_name":"Eneoji Fomentation Therapy","redeem_status":"0","voucher_amount":"2000","discount_type":2,"imagepath":"http://li120-173.members.linode.com/crm_beta/upload/"}]}
You should check if there is 2 lines with the same foreign key value in one of the inner joined table.
For ex,if you have 2 rows with total_voucher_code = "FIFLTBH8567" in table db_code, even if the reste of the row is different, you'll get this kind of unexpected result.
Try to write your SELECT statement as below
SELECT DISTINCT s.id,s.voucher_code,s.merchant etc...
Use distinct in your sql, so you don't get any duplicates rows:
$sql="select distinct s.id,s.voucher_code,s.merchant,s.date,s.receiver,s.sender,s.serial_no,s.image,s.expired_date,s.product_id,c.status,c.redeem_status,sup.supplier_id,sup.name,a.name AS sender_name,v.discount,v.discount_type,v.voucher_amount,p.Product_name AS pro_name
from db_send_evoucher_code s
INNER JOIN db_code c ON s.voucher_code=c.total_voucher_code
INNER JOIN db_supplier sup ON s.merchant=sup.supplier_id
INNER JOIN medilink_admin a ON s.sender=a.admin_id
INNER JOIN db_voucher_code v ON c.voucher_code_id=v.voucher_code_id
INNER JOIN db_product_info p ON s.product_id=p.pro_Id
where s.receiver='".$userid ."' and s.product_id='".$pro_id."'";

Setting PHP Query into a nested array

I am trying to use PHP to logically store all of that data in a nested associative arrays, and then whenever I loop through the data or need to reference the data I would refer to the array pointer rather than doing new queries each time.
For example:
My query is
$query = $db->query("
SELECT
c.id campaign_id,
c.campaign_title,
c.start_date campaign_start_date,
c.end_date campaign_end_date,
cat.id category_id,
cat.category_title,
n.id nominee_id,
n.title nominee_title,
u.id voter_id,
u.fullname voter_name
FROM
campaign c
LEFT JOIN categories cat ON cat.campaign_id = c.id
LEFT JOIN category_nominees cn ON cn.category_id = cat.id
LEFT JOIN nominees n ON n.id = cn.nominee_id
LEFT JOIN category_votes cv ON cv.campaign_id = c.id
AND cv.category_id = cat.id
AND cv.nominee_id = n.id
LEFT JOIN users u on u.id = cv.user_id
WHERE
c.active = 1
ORDER BY
u.fullname,
c.campaign_title,
cat.category_order,
cat.category_title,
cn.nominee_order,
n.title
") or die(mysqli_error());
and im trying to set up the nested array like
$array = array() ;
while($row = mysqli_fetch_assoc($query)) {
$array[$row['campaign_id']] = $row['campaign_id'];
$array[$row['campaign_id']]['campaign_title'] = $row['campaign_title'];
$array[$row['campaign_id']]['campaign_start_date'] = $row['campaign_start_date'];
$array[$row['campaign_id']]['campaign_end_date'] = $row['campaign_end_date'];
$array[$row['campaign_id']]['campaign_title'] = $row['campaign_title'];
$array[$row['campaign_id']]['category_id'] = $row['category_id'];
$array[$row['campaign_id']]['category_id']['category_title'] = $row['category_title'];
}
So whenever I point to:
$array[2][3]['category_title']
It would print the category title
Do you have any ideas? I literally been at it for months and can't figure it out.
Use the following:
while ($row = mysqli_fetch_assoc($query)) {
if (!isset($row['campaign_id'])) {
$array[$row['campaign_id']] = $row;
}
if (!isset($array[$row['campaign_id']]['categories'])) {
$array[$row['campaign_id']]['categories'] = array();
}
$array[$row['campaign_id']]['categories'][$row['category_id']] = array('category_id' => $row['category_id'], 'category_title' => $row['category_title']);
}
}
$row is already an associative array, you don't need to assign each element separately. You only need to deal specially with the category information, which has to be put into a nested associative array that I've called categories. So you would access it as
$array[0]['categories'][1]['category_title']
You can loop over all the categories with:
foreach ($array[$campaign]['categories'] as $cat) {
echo "Category ID: {$cat['category_id']} Title: {$cat['category_title']}<br>";
}

Associative array always returns only 4 result

Hi want to create a associative array for below query result :
$sql = "select s.*,di.dealsimage,
ctm.city,
l.location,
GROUP_CONCAT(DISTINCT cm.cuisine ORDER BY scr.cuisine_sequence_for_store) AS cui,
GROUP_CONCAT(DISTINCT rtm.restaurant_type ORDER BY srr.rest_type_sequence_for_store) AS restauranttype
from stores s
left join city_master ctm on s.city_id = ctm.city_id
left join locations l on s.location_id = l.location_id
left join store_cuisine_relation scr on s.store_id = scr.store_id
left join cuisine_master cm on scr.cuisine_id = cm.cuisine_id
left join store_resttype_relation srr on s.store_id = srr.store_id
left join restaurant_type_master rtm on rtm.rest_type_id = srr.rest_type_id
left join store_dealcat_relation sdr on s.store_id = sdr.store_id
left join deals_category_master dcm on dcm.deal_cat_id = sdr.deal_cat_id
left join deals_image di on di.`store_id` = s.store_id
where $condition1 s.is_active = 1 $condition2 group by (s.store_id) order by s.store_id";
//echo $sql;exit;
//echo $sql;exit;
$sqlex1 = mysqli_query($db,$sql);
$custom_count = #mysqli_num_rows($sqlex1); // it prints 28
while($result1 = mysqli_fetch_assoc($sqlex1)){
$dataArr = array_push_assoc($dataArr, 'store_id', $result1['store_id']);
$dataArr = array_push_assoc($dataArr, 'store_name', $result1['store_name']);
$dataArr = array_push_assoc($dataArr, 'store_logo', $result1['store_image_url']);
$dataArr = array_push_assoc($dataArr, 'deals_image', $result1['dealsimage']);
}
//echo count($dataArr);exit;
//echo $kl;exit;
//$result = array_merge_recursive($gpsArr,$dataArr);
function array_push_assoc($array, $key, $value){
$array[$key][] = $value;
return $array;
}
The query returns 28 result but when I try to echo the count of $dataArr it prints 4 always. What im doing wrong ? How can I achieve this ?
Thanks in advance
Becasue your function array_push_assoc() creates array with 4 keys store_id, store_name,store_logo, anddeals_image`, and each key has 28 rows
Try this:
dataArr = array();
while($result1 = mysqli_fetch_assoc($sqlex1))
{
$dataArr[] = array('store_id'=>$result1['store_id'],
'store_name'=>$result1['store_name'],
'store_logo'=>$result1['store_image_url'],
'deals_image'=>$result1['dealsimage']);
}
This will create array with 28 associative arrays
Your code should be changed to:
while($result1 = mysqli_fetch_assoc($sqlex1))
{
array_push($dataArr, array ('store_id'=> $result1['store_id'], 'store_name'=> $result1['store_name'], 'store_logo'=> $result1['store_image_url'], 'deals_image'=> $result1['dealsimage']));
}

Can't get query to work

I have a database containing 3 tables (member, boat, boatType) and in the method below two of them is affected. What I want is to list all boats that's registered on a member, but there's a problem with the code (at least with the SQL, but I suspect that's not all).
Thanks in advance.
boatHandler.php:
public function GetMembersBoats($memberId) {
$query = "SELECT b.boatId, b.length, bt.type
FROM boat AS b
INNER JOIN member AS m
ON b.memberId = m.memberId
WHERE m.memberId = ?
INNER JOIN boatType AS bt
ON b.boatTypeId = bt.boatTypeId
GROUP BY b.boatId";
$stmt = $this->m_db->Prepare($query);
$stmt->bind_param('i', $memberId);
$boats = $this->m_db->GetBoats($stmt);
}
database.php:
public function GetBoats($stmt) {
$boats = array(
0 => array(),
1 => array(),
2 => array()
);
$stmt->execute();
$stmt->bind_result($boatId, $length, $type);
while ($stmt->fetch()) {
array_push($boats[0], $boatId);
array_push($boats[1], $length);
array_push($boats[2], $type);
}
$stmt->Close();
return $boats;
}
Affected tables:
boat: boatId, boatTypeId, length, memberId
boatType: boatTypeId, type
The WHERE clause has to be listed after the table references. You have to move the WHERE m.memberId = ? to the end of the table references after the FROM and JOINs like so:
SELECT b.boatId, b.length, bt.type
FROM boat AS b
INNER JOIN member AS m
ON b.memberId = m.memberId
INNER JOIN boatType AS bt
ON b.boatTypeId = bt.boatTypeId
WHERE m.memberId = ?
GROUP BY b.boatId
as you in on clause, simply replace 'where' by 'and':
SELECT b.boatId, b.length, bt.type
FROM boat AS b
INNER JOIN member AS m
ON b.memberId = m.memberId
AND m.memberId = ?
INNER JOIN boatType AS bt
ON b.boatTypeId = bt.boatTypeId
GROUP BY b.boatId

Combine mysql query with sub query results into one PHP array

I have a table that contains events, to list these events I loop through the event table, check the event type and look up it's value in it's specific table with it's eventId.
At the moment this uses one query to get the 20 events and then up to 3 queries to get the data on those events. I currently have it coded procedurally but need to change it so that at the end it just returns the data in array form.
Here's a Pseduo code example of what I need to achieve:
while(eventQuery):
if commentQueryResult;
$array .= commentQueryResult;
if forumPostQueryResult;
$array .= forumPostQueryResult;
if uploadItemQueryResult;
$array .= uploadItemQueryResult;
endwhile;
return $array; // Combined returned results as one array
I will then be able to access the data and just foreach loop through it.
I'm just not sure the best way to combine multiple result sets into an array?
OR you could try and combine them into one query ...
$eventResult = mysql_query(
'SELECT userevent.event, userevent.eventId, userevent.friendId
FROM userevent
WHERE userevent.userId = 1 OR userevent.friendId = 1
ORDER BY userevent.id DESC
LIMIT 20'
);
while ($eventRow = mysql_fetch_row($eventResult)){
if($eventRow[0] == 1){
$result = mysql_fetch_array(mysql_query("
SELECT forumRooms.id, forumRooms.title
FROM forumPosts
INNER JOIN forumRooms ON forumPosts.`forumTopic` = forumRooms.`id`
WHERE forumPosts.id = '$eventRow[1]'"));
}
elseif($eventRow[0] == 2){
$result = mysql_fetch_array(mysql_query("
SELECT game.id, game.uriTitle, game.title
FROM usergamecomment
INNER JOIN game ON usergamecomment.`gameId` = game.id
WHERE usergamecomment.id = $eventRow[1]"));
}
elseif($eventRow[0] == 4){
$result = mysql_fetch_array(mysql_query("
SELECT usercomment.comment, UNIX_TIMESTAMP(usercomment.TIME), `user`.id, `user`.username, `user`.activate
FROM usercomment
INNER JOIN `user` ON usercomment.`userId` = `user`.id
WHERE usercomment.id = $eventRow[1]
AND `user`.activate = 1"));
}
elseif($eventRow[0] == 5){
$result = mysql_fetch_array(mysql_query("
SELECT game.id, game.title, game.uriTitle
FROM game
WHERE game.id = $eventRow[1]"));
}
// Combined Results as array
}
I'm in the process of converting all of these to PDO, that's the next step after working out the best way to minimise this.
Challenge accepted. ;)
Since you are actually only interested in the results inside the while loop, you could try this single query. Due to the LEFT JOINS it might not be faster, pretty much depends on your database. The final $result contains all elements with their respective fields.
$result = array();
$q = 'SELECT userevent.event AS userevent_event,
userevent.eventId AS userevent_eventId,
userevent.friendId AS userevent_friendId,
forumRooms.id AS forumRooms_id,
forumRooms.title AS forumRooms_title,
game.id AS game_id,
game.uriTitle AS game_uriTitle,
game.title AS game_title,
usercomment.comment AS usercomment_comment,
UNIX_TIMESTAMP(usercomment.TIME) AS usercomment_time,
user.id AS user_id,
user.username AS user_username,
user.activate AS user_activate,
g2.id AS game2_id,
g2.uriTitle AS game2_uriTitle,
g2.title AS game2_title
FROM userevent
LEFT JOIN forumPosts ON forumPosts.id = userevent.eventId
LEFT JOIN forumRooms ON forumPosts.forumTopic = forumRooms.id
LEFT JOIN usergamecomment ON usergamecomment.id = userevent.eventId
LEFT JOIN game ON usergamecomment.gameId = game.id
LEFT JOIN usercomment ON usercomment.id = userevent.eventId
LEFT JOIN user ON usercomment.userId = user.id
LEFT JOIN game g2 ON userevent.eventId = g2.id
WHERE (userevent.userId = 1 OR userevent.friendId = 1)
AND userevent.eventId >= (SELECT userevent.eventId
WHERE userevent.userId = 1 OR userevent.friendId = 1
ORDER BY userevent.id DESC LIMIT 1,20);';
$r = mysql_query($q);
while ( $o = mysql_fetch_row($r) ) {
switch($o['userevent_event']) {
case 1:
$result[] = array(
'id' => $o['forumsRooms_id'],
'title' => $o['forumsRooms_title'],
);
break;
case 2:
$result[] = array(
'id' => $o['game_id'],
'uriTitle' => $o['game_uriTitle'],
'title' => $o['game_title'],
);
break;
case 4:
$result[] = array(
'comment' => $o['usercomment_comment'],
'time' => $o['usercomment_time'],
'id' => $o['user_id'],
'username' => $o['user_username'],
'activate' => $o['user_activate'],
);
break;
case 5:
$result[] = array(
'id' => $o['game2_id'],
'uriTitle' => $o['game2_uriTitle'],
'title' => $o['game2_title'],
);
break;
}
}
Note: Eventually, the query has to be edited slightly, I just wrote that out of my head w/o testing. Optimization can surely be done if I'd knew more about the db structure.
Also, this is merely a proof of concept that it can indeed be done with a single query. ;)

Categories