PHP - Nesting an array from API obj response - php

I have a large object API response, I'm trying to load the data into a nested array so I can work with it later. Here is a sample of the object I get back from the API.
SObject Object
(
[type] => AggregateResult
[fields] => stdClass Object
(
[expr0] => 12
[Name] => Performance Reviews
[Status] => Closed - Approved
[expr1] => 30
)
)
SObject Object
(
[type] => AggregateResult
[fields] => stdClass Object
(
[expr0] => 12
[Name] => Performance Reviews
[Status] => Closed - Attempted
[expr1] => 11
)
)
SObject Object
(
[type] => AggregateResult
[fields] => stdClass Object
(
[expr0] => 12
[Name] => Performance Reviews
[Status] => Closed - Contact Declined
[expr1] => 13
)
As I said, the goal is to have a nested array that would look similar to this:
Array
(
[January] => Array
(
[0] => Array
(
[0] => January
[1] => Closed - Approved
[2] => 28
)
[1] => Array
(
[0] => January
[1] => Closed - Approved
[2] => 28
)
)
)
Here is my Code:
$query =
"SELECT CALENDAR_MONTH(closedDate), recordType.name,status,count(id)
FROM case
WHERE owner.name ='" . $SFName . "' AND recordType.name IN('DT Case','Performance Reviews') AND closedDate = LAST_N_MONTHS:6
GROUP BY CALENDAR_MONTH(closedDate),recordType.Name,status ORDER BY CALENDAR_MONTH(closedDate)";
$counter = 0;
$mprArray = array(); //instantiate our Array
$response = $mySforceConnection->query($query);
$queryResult = new QueryResult($response);
foreach ($queryResult->records as $case) {
//turn our query Result into an Obj
$sObject = new SObject($case);
$recordType = $sObject->Name;
$status = $sObject->Status;
$month = $sObject->expr0;
$count = $sObject->expr1;
//this is a filter to weed out a portion of the cases.
if ($recordType == "Performance Reviews") {
foreach($sObject as $record) {
//change the month's number to a month's name
$dateObj = DateTime::createFromFormat('!m', $month);
$monthName = $dateObj->format('F');
// Create the nested array, it should end up looking like $mprArray[January].
// This is a dynamic name since we're creating an array for each status that exists in performance Reviews
$mprArray[$monthName] = array($monthName,$status,$count);
// Trying to append our nested array onto the $mprArray so we can work with it later.
array_push($mprArray,$mprArray[$monthName]);
}
}
//increase counter
$counter = $counter++;
}
} catch (Exception $e) {
print_r($mySforceConnection->getLastRequest());
echo $e->faultstring;
}
Instead of a nested array, only the first item in the array is named 'January', the remainder are named based on a counter, until we get to the next month of 'february', here's what it looks like.
Array
(
[January] => Array
(
[0] => January
[1] => Closed - Contact Declined
[2] => 15
)
[0] => Array
(
[0] => January
[1] => Closed - Approved
[2] => 28
)
)

because array_push only inserts the data to the next index;
I feel you should use $mprArray[$monthName][] = array($monthName,$status,$count); only; and no need for the array_push after that

Related

Identify if array in object. Php

Working against an API for an accounting system and wondering how to handle the return of fiscals years. I want to iterate each fiscal year, which is no problem if there are multiple fiscal years. However if there is only one fiscal year the returned object/array is slightly different, how should I handle this, ie how to identify the subarray?
//Example data if multiple fiscal years
stdClass Object
(
[GetFiscalYearsResult] => stdClass Object
(
[FiscalYear] => Array
(
[0] => stdClass Object
(
[Id] => 257c2e5e-2b5b-4eea-9405-775caef357d4
[StartingDate] => 2015-01-01T00:00:00Z
[EndingDate] => 2016-01-01T00:00:00Z
[IsLocked] =>
)
[1] => stdClass Object
(
[Id] => 376ce224-77ce-43cd-b3c4-a3703b1fc8bf
[StartingDate] => 2018-01-01T00:00:00Z
[EndingDate] => 2019-01-01T00:00:00Z
[IsLocked] =>
)
)
)
)
//Example data if one fiscal year
stdClass Object
(
[GetFiscalYearsResult] => stdClass Object
(
[FiscalYear] => stdClass Object
(
[Id] => f2712737-9c63-4c4b-b107-1b841985cffb
[StartingDate] => 2019-01-01T00:00:00Z
[EndingDate] => 2020-01-01T00:00:00Z
[IsLocked] =>
)
)
)
//Current php code for multiple fiscal years
$Result = $Service->GetFiscalYears();
foreach($Result->GetFiscalYearsResult->FiscalYear as $item=>$object) {
$YE = date('Y-m-d',(strtotime ( '-1 day' , strtotime ( $object -> EndingDate) ) ));
echo $YE
}
//EDIT With solution (identification of subarray with is_array)
$Result = $Service->GetFiscalYears();
if(is_array($Result->GetFiscalYearsResult->FiscalYear)){
foreach($Result->GetFiscalYearsResult->FiscalYear as $item=>$object) {
CODE
}
} else { //if only one fiscal year
CODE
}

PHP Nested foreach with Key

I have been trying to work this out for two days now and am hitting a brick wall. I have a skyscanner array that has flight itineraries where I have the flight
Leg - being Itineraries -> OutboundLegId -
and also the legs which shows the flight number - being
Legs -> FlightNumbers -> FlightNumber.
What I am trying to achieve is to display the Itinerary and then join the Flight Number on to that. But no matter what I try I cannot get this to work. I have read all about Keys on here and tried loads of examples but am coming up with nothing. Can someone point me in the right direction please?
Example arrays below
[Itineraries] => Array
(
[0] => Array
(
[OutboundLegId] => 13542-1610140610-29-0-13445-1610141240
[InboundLegId] => 13445-1610211340-29-0-13542-1610211640
[PricingOptions] => Array
(
[0] => Array
(
[Agents] => Array
(
[0] => 2174187
)
[QuoteAgeInMinutes] => 31
[Price] => 200.98
[DeeplinkUrl] => http://partners.api.skyscanner.net/apiservices/deeplink/v2?_cje=5JlLCgyPUKY0hT8T0Ybh6dL0Xf0htAiHTFX7RU79eeI3XvrsxvEqP1QUJAoHiHRd&url=http%3a%2f%2fwww.apideeplink.com%2ftransport_deeplink%2f4.0%2fUK%2fen-gb%2fGBP%2fcook%2f2%2f13542.13445.2016-10-14%2c13445.13542.2016-10-21%2fair%2fairli%2fflights%3fitinerary%3dflight%7c-32294%7c1152%7c13542%7c2016-10-14T06%3a10%7c13445%7c2016-10-14T12%3a40%2cflight%7c-32294%7c1153%7c13445%7c2016-10-21T13%3a40%7c13542%7c2016-10-21T16%3a40%26carriers%3d-32294%26passengers%3d1%2c0%2c0%26channel%3ddataapi%26cabin_class%3deconomy%26facilitated%3dfalse%26ticket_price%3d200.98%26is_npt%3dfalse%26is_multipart%3dfalse%26client_id%3dskyscanner_b2b%26request_id%3d3bc96bda-fd7c-403a-b841-2ccc3c26071d%26commercial_filters%3dfalse%26q_datetime_utc%3d2016-09-29T08%3a18%3a27
)
[Legs] => Array
(
[0] => Array
(
[Id] => 13542-1610140610-29-0-13445-1610141240
[SegmentIds] => Array
(
[0] => 1
)
[OriginStation] => 13542
[DestinationStation] => 13445
[Departure] => 2016-10-14T06:10:00
[Arrival] => 2016-10-14T12:40:00
[Duration] => 270
[JourneyMode] => Flight
[Stops] => Array
(
)
[Carriers] => Array
(
[0] => 105
)
[OperatingCarriers] => Array
(
[0] => 105
)
[Directionality] => Outbound
[FlightNumbers] => Array
(
[0] => Array
(
[FlightNumber] => 1152
[CarrierId] => 105
)
)
)
Assuming this is one big array and its called $data you can nest a couple of foreach loops.
I use foreach loops as I assume there are cases where this data structure get more complex than the one you show
foreach ( $data['Itineraries'] as $itin ) {
foreach ( $data['Legs'] as $legs) {
if ($legs['Id'] == $itin['OutboundLegId']) {
// we matched the itinerary with a leg
echo $legs['OutboundLegId'] . ' ' . $legs['FlightNumbers'][0]['FlightNumber'];
}
}
}
Use it as draft. Can't perform function without feedback.
Put proper arrays instead of {YOUR-ARRAY-WITH-LEGS} and {YOUR-ARRAY-WITH-ITINERARIES}
$sortedLegs = array_column('Id', {YOUR-ARRAY-WITH-LEGS});
$joinedArray = array_map(function($itinerary) use($sortedLegs){
if(array_key_exists($itinerary['OutboundLegId'],$sortedLegs)) {
$itinerary['legs'] = $sortedLegs[$itinerary['OutboundLegId']];
}
return $itinerary;
},{YOUR-ARRAY-WITH-ITINERARIES});

Laravel Pagination merge

I'm using laravel 4 for my project .
I have paginated select results from 4 tables and I wanted to pass them to view in one variable .
$vehicles = DB::table('vehicle')->orderBy('postTime','DESC')->paginate(8);
$estates = DB::table('estate')->orderBy('postTime','DESC')->paginate(8);
$tradings = DB::table('trading')->orderBy('postTime','DESC')->paginate(8);
$jobs = DB::table('job')->orderBy('postTime','DESC')->paginate(8);
but I could not merge them using array_merge() . I also tried ->to_array() after paginate, it didn't work.
can some one help me here ?
EDIT
as #Turgut Sarıçam suggested , I used getItems() for my results and here is my code :
public static function index(){
$minVehicle = DB::table('vehicle')->min('price');
$maxVehicle = DB::table('vehicle')->max('price');
$minEstate = DB::table('estate')->min('price');
$maxEstate = DB::table('estate')->max('price');
$minTrading = DB::table('trading')->min('price');
$maxTrading = DB::table('trading')->max('price');
if($minVehicle == 'توافقی')
$minVehicle = 0;
if($maxVehicle == 'توافقی')
$maxVehicle = 0;
if($minEstate == 'توافقی')
$minEstate = 0;
if($maxEstate == 'توافقی')
$maxEstate = 0;
if($minTrading == 'توافقی')
$minTrading = 0;
if($maxTrading == 'توافقی')
$maxTrading = 0;
$vehicles = DB::table('vehicle')->orderBy('postTime','DESC')->paginate(8);
$estates = DB::table('estate')->orderBy('postTime','DESC')->paginate(8);
$tradings = DB::table('trading')->orderBy('postTime','DESC')->paginate(8);
$jobs = DB::table('job')->orderBy('postTime','DESC')->paginate(8);
$allResults = array_merge($vehicles,$jobs);
//echo "<meta charset='UTF8'><pre>";
//return die(print_r($allResults));
return View::make('search')->with(
array(
'minVehicle' => $minVehicle,
'maxVehicle' => $maxVehicle,
'minEstate' => $minEstate,
'maxEstate' => $maxEstate,
'minTrading' => $minTrading,
'maxTrading' => $maxTrading,
'ads' => $allResults
)
);
}
Dumping $allResults (where I commented) had some results.
I cant show the exact result , but here is example of it :
Array
(
[0] => stdClass Object
(
[id] => 243
[tableName] => vehicle
)
[1] => stdClass Object
(
[id] => 239
[tableName] => vehicle
)
[2] => stdClass Object
(
[id] => 235
[tableName] => vehicle
)
[3] => stdClass Object
(
[id] => 231
[tableName] => vehicle
)
[4] => stdClass Object
(
[id] => 227
[tableName] => vehicle
)
[5] => stdClass Object
(
[id] => 223
[tableName] => vehicle
)
[6] => stdClass Object
(
[id] => 219
[tableName] => vehicle
)
[7] => stdClass Object
(
[id] => 215
[tableName] => vehicle
)
[8] => stdClass Object
(
[id] => 4
[tableName] => job
)
[9] => stdClass Object
(
[id] => 3
[tableName] => job
)
)
although the result seems to be fair , no view was returned . just a blank white page
You should get the items first. Try like this:
$allResults = array_merge($vehicles->items(), $estates->items(), $tradings->items(), $jobs->items());
Edit: I guess you can get items with getItems() function in Laravel 4. Above is for Laravel 5, my bad.
You are dealing with collections that are returned from the query. Don't think array merge is correct way to go Try using collection merge.
Collection merge is supported as well in laravel 4.
Try using this
$merged_collection = $vehicles->merge($estates)->merge($tradings)->merge($jobs);

Formatting an array to order by specified unix timestamp in PHP

I have an array which has a timestamp consistently on [3] ( an example of the array data below)
I would like the array to be sorted using the timestamp. I've seen a few stackoverflow posts that apparently do this using two methods, array_multisort() and usort() but I've been unable to replicate either.
Here is what I've tried based on my own code:
Attempt 1 - I pass the array to usort, then attempt to take it apart with the foreach. Applying this method definitely changes the order of the results, but the dates seems to be no specific order (ascending, descending).
function sortArray($a1, $a2){
if ($a1[3] == $a2[3]) return 0;
return ($a1[3] > $a2[3]) ? -1 : 1;
}
usort($the_array, "sortArray");
foreach($the_array as $sh) {
$uid = $sh['uid'];
$username = $sh['username'];
$datetime = $sh['datetime'];
$type = $sh['type'];
echo "<p> $uid , $username, $datetime, $type </p>";
}
Attempt 2 - tried using array_multisor() which again gives me results in a different order but I don't understand what it is sorting by exactly.
foreach ($the_array as $key => $node) {
$timestamps[$key] = $node[3];
}
array_multisort($timestamps, SORT_ASC, $the_array);
//process the array with a foreach to show results
My theory here is that it isn't properly processing the unix timestamp and I'm not sure what I can do about that. Is it smart to take out all the characters of the timestamp so it is a simple line of numbers ( 2014-01-02 03:02:12 becomes 20140102030212 )? Or is there another way to process it with the timestamp in it's current form?
Here is an example of the data in the array:
Array
(
[0] => Array
(
[uid] => 20013
[0] => 20013
[username] => myhipswontlie
[1] => myhipswontlie
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-27 23:40:56
[3] => 2014-01-27 23:40:56
[type] => rated
[4] => rated
)
[1] => Array
(
[uid] => 20025
[0] => 20025
[username] => brasilchika
[1] => brasilchika
[rating] => 4.00
[2] => 4.00
[datetime] => 2014-01-02 03:02:12
[3] => 2014-01-02 03:02:12
[type] => rated
[4] => rated
)
[2] => Array
(
[uid] => 10002
[0] => 10002
[username] => crtten
[1] => crtten
[datetime] => 2014-01-25 01:33:34
[2] => 2014-01-25 01:33:34
[type] => visits
[3] => visits
)
)
Your issue is your numeric keys don't seem to match up in your arrays. Sometimes the datetime is found in the 3rd key, sometime it is found in the second key (which is odd considering they look like they come from mysql_fetch_array() which will make uniform arrays).
To solve this you should use the associative array key instead:
function sortArray($a1, $a2){
if ($a1['datetime'] == $a2['datetime']) return 0;
return ($a1['datetime'] > $a2['datetime']) ? -1 : 1;
}
usort($the_array, "sortArray");

mysql unexpected output from query [duplicate]

This question already has answers here:
mysql_fetch_array returns duplicate data
(7 answers)
Closed 9 years ago.
Maybe I have long since gotten to used to using ORM methods to pull data from a DB but I am now working up a simple little project for a buddy of mine who doesn't need all the extra guff of MVC's, ORM's and so on.. With that below is an example of the query I am putting together in a class I am building up in PHP.
$this->sqlstart();
$sql = "select label, setting from ".$this->_settings." where id <= 4";
$query = mysql_query($sql);
$result = array();
while($row = mysql_fetch_array($query))
{
$result[] = $row;
}
return $result;
The output from return $result is:
Array
(
[0] => Array
(
[0] => Week 1 Pay
[label] => Week 1 Pay
[1] => 2995
[setting] => 2995
)
[1] => Array
(
[0] => Week 2 Pay
[label] => Week 2 Pay
[1] => 2995
[setting] => 2995
)
[2] => Array
(
[0] => Week 1 Dates
[label] => Week 1 Dates
[1] => 1-15
[setting] => 1-15
)
[3] => Array
(
[0] => Week 2 Dates
[label] => Week 2 Dates
[1] => 16-31
[setting] => 16-31
)
)
And it should be
Array
(
[0] => Array
(
[label] => Week 1 Pay
[setting] => 2995
)
[1] => Array
(
[label] => Week 2 Pay
[setting] => 2995
)
[2] => Array
(
[label] => Week 1 Dates
[setting] => 1-15
)
[3] => Array
(
[label] => Week 2 Dates
[setting] => 16-31
)
)
can anyone point out to me where the additional data in the sets is coming from?
You should use mysql_fetch_assoc to get the result properly. It will provide you an associative array instead of a normal one.
From http://php.net/manual/en/function.mysql-fetch-array.php
array mysql_fetch_array ( resource $result [, int $result_type = MYSQL_BOTH ] )
Either pass MYSQL_ASSOC as the second param to just get an associative array back, or just call mysql_fetch_assoc().
You should be able to pass in a second argument which will only output the associative column names:
while($row = mysql_fetch_array($query, MYSQL_ASSOC))
mysql_fetch_array returns two ways to access values: field name and index number. You might change mysql_fetch_array to mysql_fetch_assocor change the code to:
while($row = mysql_fetch_array($query)){
$result[] = array('label' => $row['label'], 'setting' => $row['setting'];
}

Categories