php object access from json - php

I have a json reply from an api and i want some data.
the response looks like this:
{
"user_id": null,
"flight_info": {
"YU24268": {
"seat": {
"width": 45.72,
"pitch": 73.66
},
"delay": {
"ontime_percent": 0.66666669,
"max": 53,
"mean": 37,
"min": 28
}
},
"delay": {
"ontime_percent": 0.67741936,
"max": 305,
"mean": 33,
"min": 0
}
}
},
"travelpayouts_api_request": true,
"clean_marker": "75089",
"currency": "usd",
"internal": false,
"airports": {
"ORY": {
"rates": "12",
"city_code": "PAR",
"country_code": "FR",
"country": "France",
"time_zone": "Europe/Paris",
"name": "Paris Orly Airport",
"city": "Paris"
},
"SXF": {
"rates": "27",
"city_code": "BER",
"country_code": "DE",
"country": "Germany",
"time_zone": "Europe/Berlin",
"name": "Schonefeld Airport",
"city": "Berlin"
}
}
I use this code to find the airport i need (from the IATA code), but i can not get the city.
function find_city_from_IATA($my_value, $key1)
{
foreach ($key1->airports as $key=>$value) {
echo $key;
echo $my_value;
if ($key==$my_value) {
$city = json_decode($key1->airports,true);
// echo $key1->airlines['U2']->city;
$city = $city->city;
echo $city;
return $city;
}
}
}
How can i get the city name based on the airport IATA? (iata is the three letter code key that airports objects have).

Something like this:
$airport_code = 'ORY';
// $my_irpost_string is your json string
$data = json_decode($my_json_string, true);
$city = $data['airports'][$airport_code]['city'];
print($city);
You don't need foreach, as you already know the code. This means that your foreach + comparison is just array value # code.
This is a well known antipattern: https://softwareengineering.stackexchange.com/questions/348682/what-is-the-for-case-antipattern

Related

Parsing Json into php table results in Undefined index

I am accessing API for "ConnectWise". the data comes into JSON format. i was able to parse the data into table via PHP. however, empty fields in JSON results in Undefined index. This happens for some items with no website, or address for example. the rest shows up fine.
Any help or input would be appreciated.
Here is my code to get the data from Connectwise:
function get_companies(){
$curl = curl_init();
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($curl, CURLOPT_URL, "https://api-
na.myconnectwise.net/v4_6_release/apis/3.0/company/companies");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
"Authorization: Basic (OUR KEY)",
'Content-type: application/json'
));
$result = curl_exec($curl);
curl_close($curl);
$decoded = json_decode($result,true);
return $decoded;
}
And to display the data:
function list_all_accounts(){
$accounts = get_companies();
if ( !empty ($accounts)){
foreach ($accounts as $account) {
{
echo "
</td>
<td>
$account[id]
</td>
<td>
$account[name]
</td>
<td>
$account[addressLine1]
</td>
<td>
$account[phoneNumber]
</td>
<td>
$account[website]
</td>
<td>
$account[name]
</td>
</tr>";
}
}
}
}
Update - Json Sample
[
{
"id": 250,
"identifier": "company name ",
"name": "company name",
"status": {
"id": 1,
"name": "Active",
"_info": {
"status_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies/statuses/1"
}
},
"type": {
"id": 1,
"name": "Client",
"_info": {
"type_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies/types/1"
}
},
"addressLine1": "address line 1",
"city": "New York",
"state": "NY",
"zip": "11111",
"country": {
"id": 1,
"name": "United States",
"_info": {
"country_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/countries/1"
}
},
"phoneNumber": "123456789",
"faxNumber": "",
"website": "www.site.com",
"territoryId": 2,
"accountNumber": "",
"dateAcquired": "2006-06-21T04:00:00Z",
"sicCode": {
"id": 1209,
"name": "consulting"
},
"annualRevenue": 0,
"timeZone": {
"id": 1,
"name": "GMT-5/Eastern Time: US & Canada",
"_info": {
"timeZoneSetup_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/system/timeZoneSetups/1"
}
},
"leadFlag": false,
"unsubscribeFlag": false,
"userDefinedField5": "1",
"taxCode": {
"id": 8,
"name": "Tax-State",
"_info": {
"taxCode_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/finance/taxCodes/8"
}
},
"billingTerms": {
"id": 1,
"name": "Net 30 days"
},
"billToCompany": {
"id": 250,
"identifier": "comp1 ",
"name": "company1.",
"_info": {
"company_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies/250"
}
},
"billingSite": {
"id": 1291,
"name": "company1",
"_info": {
"site_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies"
}
},
"invoiceDeliveryMethod": {
"id": 1,
"name": "Mail"
},
"deletedFlag": false,
"mobileGuid": "1df91371-6d7a-4778-ab81-f3e7761f5211",
"currency": {
"id": 7,
"symbol": "$",
"isoCode": "USD",
"name": "US Dollars",
"_info": {
"currency_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/finance/currencies/7"
}
},
"_info": {
"lastUpdated": "2018-04-02T16:36:05Z",
"updatedBy": "user1",
"dateEntered": "2006-06-21T16:04:59Z",
}
},
{
"id": 250,
"identifier": "company name ",
"name": "company name",
"status": {
"id": 1,
"name": "Active",
"_info": {
"status_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies/statuses/1"
}
},
"type": {
"id": 1,
"name": "Client",
"_info": {
"type_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies/types/1"
}
},
"addressLine1": "address line 1",
"city": "New York",
"state": "NY",
"zip": "11111",
"country": {
"id": 1,
"name": "United States",
"_info": {
"country_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/countries/1"
}
},
"phoneNumber": "123456789",
"faxNumber": "",
"website": "www.site.com",
"territoryId": 2,
"accountNumber": "",
"dateAcquired": "2006-06-21T04:00:00Z",
"sicCode": {
"id": 1209,
"name": "consulting"
},
"annualRevenue": 0,
"timeZone": {
"id": 1,
"name": "GMT-5/Eastern Time: US & Canada",
"_info": {
"timeZoneSetup_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/system/timeZoneSetups/1"
}
},
"leadFlag": false,
"unsubscribeFlag": false,
"userDefinedField5": "1",
"taxCode": {
"id": 8,
"name": "Tax-State",
"_info": {
"taxCode_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/finance/taxCodes/8"
}
},
"billingTerms": {
"id": 1,
"name": "Net 30 days"
},
"billToCompany": {
"id": 250,
"identifier": "comp1 ",
"name": "company1.",
"_info": {
"company_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies/250"
}
},
"billingSite": {
"id": 1291,
"name": "company1",
"_info": {
"site_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/company/companies"
}
},
"invoiceDeliveryMethod": {
"id": 1,
"name": "Mail"
},
"deletedFlag": false,
"mobileGuid": "1df91dd371-6d7addd-4778s-ab81-f3e7761f5211",
"currency": {
"id": 7,
"symbol": "$",
"isoCode": "USD",
"name": "US Dollars",
"_info": {
"currency_href": "https://api-na.myconnectwise.net/v4_6_release/apis/3.0/finance/currencies/7"
}
},
"_info": {
"lastUpdated": "2018-04-02T16:36:05Z",
"updatedBy": "user1",
"dateEntered": "2006-06-21T16:04:59Z",
"enteredBy": "CONVERSION",
}
}
]
json_decode() and https://jsonlint.com/ both complain about the comma after the value on lines 95 and 194. Removing them makes it valid json, after which your code works as soon as you remember to quote the key values for the associative array.
I removed the two offending commas in the json and saved as a file, then added the quoting for your key values on the array, and finally removed the HTML table stuff and such (I'm just running it on command line to see output). Should be easy to put back in...
<?php
function get_companies() {
$j = file_get_contents("json.json");
$jd = json_decode($j, true);
return $jd;
}
$accounts = get_companies();
if (!empty($accounts)) {
foreach ($accounts as $account) {
echo "\n".$account['id'] . "
" . $account['name'] . "
" . $account['addressLine1'] . "
" . $account['phoneNumber'] . "
" . $account['website'] . "
" . $account['name']."\n\n";
}
}
?>
According to your comment, it is possible that some properties that you use in your HTML are not part of the JSON you receive. This means you are accessing an array index that is not set, e.g. with $account[website].
I see two solutions for this:
Only output the data if it is set in the array:
echo '<td>'.(isset($account['website']) ? $account['website'] : '').'</td>';
Use a an array with defaults for all the values as base for your $account array and merge them:
$base = [
'website' => 'no website',
'phoneNumber' => '',
];
foreach ($accounts as $account) {
// this will override all elements of $base with them of $account,
// but only if they are present in $account
$account = array_merge($base, $account);
// ... your output here ...
}

Getting information from nested arrays php

I am making calls to an API
I have the response as an associative array so that I can use:
$field = $response['nameOfKey'];
However, some of the values for keys are themselves arrays like the following:
{
"Title": "Mr",
"Forenames": "Steve",
"Surname": "Williams",
"CountryOfBirth": 1,
"EmailAddress": "john.doe#email.com",
"EmailType": "Personal",
"BirthDate": "\/Date(632880000000)\/",
"Suffix": null,
"NationalInsuranceNumber": null,
"PrimaryAddress": {
"Address1": "Flat 1",
"Address2": "Oxford Street",
"City": "London",
"County": "London",
"Postcode": "L12456",
"Country": 1
},
"AdditionalAddresses": [
{
"Address1": null,
"Address2": null,
"City": null,
"County": null,
"Postcode": null,
"Country": 0,
"AddressType": 0
}
],
"PrimaryTelephone": {
"Number": "123456789",
"DialingCode": 1,
"TelephoneType": 1
},
"AdditionalTelephone": [
{
"Number": "223456789",
"DialingCode": 2,
"TelephoneType": 2
}
],
"BankAccount": {
"AccountName": "John Doe Account",
"AccountNumber": "123456789",
"SortCode": "123456"
},
"PrimaryCitizenship": {
"CountryOfResidency": 1,
"TaxIdentificationNumber": "AB12CD34EF56"
},
"AdditionalCitizenship": [
{
"CountryOfResidency": 0,
"TaxIdentificationNumber": null
}
],
"ExternalCustomerId": "91",
"ExternalPlanId": "91",
"PlanType": 10
}
So at the moment to get Forename I can just do $forename = $decodedResponse["Forenames"]; but I'm quite baffled at trying to get values from the inner arrays.
I thought I could do something like this:
foreach($decodedResponse as $data)
{
foreach($data['TelephoneNumbers'] as $tel)
{
echo $tel['Number']; die();
}
}
Essentially loop through the original Associative array and then loop through a specific key to get its values.
Your should use foreach for following array items: AdditionalAddresses, AdditionalTelephone and AdditionalCitizenship. Otherwise just chain array keys. See examples:
$forename = $decodedResponse['Forenames'];
$address2 = $decodedResponse['PrimaryAddress']['Address2'];
foreach ($decodedResponse['AdditionalTelephone'] as $tel) {
echo $tel['Number'];
}

How to echo nested JSON object in php

I'm trying to figure out how to echo the address1 out of the JSON below. I've tried this - echo "$arr->location[1]->address1<br>";, but it returns this error
Catchable fatal error: Object of class stdClass could not be converted to string in /home/benrud/public_html/student/webdesign/2016/02_benrud/tinker/data/index.php on line 202.
echo $arr; returns the JSON below.
{
"photos": [
"https://s3-media2.fl.yelpcdn.com/bphoto/37El1q8mqM_1tKtQugncZQ/o.jpg",
"https://s3-media1.fl.yelpcdn.com/bphoto/GLsNPPz5do-_NJktIQvz6w/o.jpg",
"https://s3-media3.fl.yelpcdn.com/bphoto/Z4rdHERgb10MZgDXnct5lA/o.jpg"
],
"coordinates": {
"latitude": 33.0479031276,
"longitude": -117.256002333
},
"image_url": "https://s3-media1.fl.yelpcdn.com/bphoto/37El1q8mqM_1tKtQugncZQ/o.jpg",
"is_claimed": false,
"id": "oscars-mexican-seafood-encinitas-2",
"review_count": 48,
"rating": 4.5,
"hours": [
{
"hours_type": "REGULAR",
"is_open_now": true,
"open": [
{
"is_overnight": false,
"end": "2100",
"day": 0,
"start": "0800"
},
{
"is_overnight": false,
"end": "2100",
"day": 1,
"start": "0800"
},
{
"is_overnight": false,
"end": "2100",
"day": 2,
"start": "0800"
},
{
"is_overnight": false,
"end": "2100",
"day": 3,
"start": "0800"
},
{
"is_overnight": false,
"end": "2200",
"day": 4,
"start": "0800"
},
{
"is_overnight": false,
"end": "2200",
"day": 5,
"start": "0800"
},
{
"is_overnight": false,
"end": "2100",
"day": 6,
"start": "0800"
}
]
}
],
"display_phone": "(760) 487-5778",
"categories": [
{
"alias": "seafood",
"title": "Seafood"
},
{
"alias": "mexican",
"title": "Mexican"
}
],
"price": "$",
"phone": "+17604875778",
"name": "Oscars Mexican Seafood",
"location": {
"zip_code": "92024",
"address3": null,
"address1": "115 N El Camino Real",
"country": "US",
"city": "Encinitas",
"state": "CA",
"cross_streets": "Via Molena & Encinitas Blvd",
"display_address": [
"115 N El Camino Real",
"Encinitas, CA 92024"
],
"address2": ""
},
"transactions": [],
"url": "https://www.yelp.com/biz/oscars-mexican-seafood-encinitas-2?adjust_creative=YqqOIA_bNY3Qb_A1TRMMUg&utm_campaign=yelp_api_v3&utm_medium=api_v3_business_lookup&utm_source=YqqOIA_bNY3Qb_A1TRMMUg",
"is_closed": false
}
Location isn't an array, so I'd imagine just $arr->location->address1.
$arr = json_decode($json, true);
the true parameter makes sure it's an array and not an object
You must first decode then call the key so:
// Decode the JSON STRING
$arr = json_decode($arr, true);
/*
* first argument is the JSON STRING,
* Second sets the flag that the string is a dictionary
* (associative array)
*/
Now it is time to call the element. I put it in a conditional so to prevent errors
if (array_key_exists('address1', $arr['location'])) {
echo $arr['location']['address1'];
}
else {
echo "Array element Not Found. Here is what I have:\n\r";
print_r($arr);
}
This Should return your element's value OR Dump the parsed PHP Array for review so you can edit the if statement to get the correct location.

Referencing an appendix in JSON using PHP

I am currently developing against the FlightStats Schedules API, this is for a user to be able to search for flight schedules on a given route, on a given date.
End point looks like so
https://api.flightstats.com/flex/schedules/rest/v1/json/from/{departing_airport}/to/{arriving_airport}/departing/{YYYY/MM/DD}?appId=APP_ID&appKey=API_KEY&codeType=iata&extendedOptions=includeDirects
User will specify departing_airport, arriving_airport and date as YYYY/MM/DD
To give an example response, I'll use MEL, NRT and 2015/11/12 respectively
{
"request": {
"departureAirport": {
"requestedCode": "mel",
"fsCode": "MEL"
},
"arrivalAirport": {
"requestedCode": "nrt",
"fsCode": "NRT"
},
"codeType": {
"requested": "iata",
"interpreted": "IATA"
},
"departing": true,
"date": {
"year": "2015",
"month": "11",
"day": "12",
"interpreted": "2015-11-12"
},
"url": "https://api.flightstats.com/flex/schedules/rest/v1/json/from/mel/to/nrt/departing/2015/11/12"
},
"scheduledFlights": [
{
"carrierFsCode": "JQ",
"flightNumber": "23",
"departureAirportFsCode": "MEL",
"arrivalAirportFsCode": "NRT",
"stops": 0,
"departureTerminal": "2",
"arrivalTerminal": "3",
"departureTime": "2015-11-12T00:55:00.000",
"arrivalTime": "2015-11-12T08:45:00.000",
"flightEquipmentIataCode": "787",
"isCodeshare": false,
"isWetlease": false,
"serviceType": "J",
"serviceClasses": [
"R",
"F",
"J",
"Y"
],
"trafficRestrictions": [],
"codeshares": [
{
"carrierFsCode": "JL",
"flightNumber": "5086",
"serviceType": "J",
"serviceClasses": [
"Y"
],
"trafficRestrictions": [],
"referenceCode": 2088960
}
],
"referenceCode": "1492-2106903--"
},
{
"carrierFsCode": "JL",
"flightNumber": "5086",
"departureAirportFsCode": "MEL",
"arrivalAirportFsCode": "NRT",
"stops": 0,
"departureTerminal": "2",
"arrivalTerminal": "3",
"departureTime": "2015-11-12T00:55:00.000",
"arrivalTime": "2015-11-12T08:45:00.000",
"flightEquipmentIataCode": "787",
"isCodeshare": true,
"isWetlease": false,
"serviceType": "J",
"serviceClasses": [
"Y"
],
"trafficRestrictions": [],
"operator": {
"carrierFsCode": "JQ",
"flightNumber": "23",
"serviceType": "J",
"serviceClasses": [
"R",
"F",
"J",
"Y"
],
"trafficRestrictions": []
},
"codeshares": [],
"referenceCode": "1492-2106903--2088960"
}
],
"appendix": {
"airlines": [
{
"fs": "JL",
"iata": "JL",
"icao": "JAL",
"name": "JAL",
"active": true
},
{
"fs": "JQ",
"iata": "JQ",
"icao": "JST",
"name": "Jetstar",
"active": true
}
],
"airports": [
{
"fs": "NRT",
"iata": "NRT",
"icao": "RJAA",
"name": "Narita International Airport",
"street1": "成田空港第2PTB(バス), Narita",
"street2": "Chiba Prefecture",
"city": "Tokyo",
"cityCode": "TYO",
"countryCode": "JP",
"countryName": "Japan",
"regionName": "Asia",
"timeZoneRegionName": "Asia/Tokyo",
"localTime": "2015-09-21T09:37:31.611",
"utcOffsetHours": 9,
"latitude": 35.773213,
"longitude": 140.387443,
"elevationFeet": 135,
"classification": 1,
"active": true
},
{
"fs": "MEL",
"iata": "MEL",
"icao": "YMML",
"name": "Tullamarine Airport",
"city": "Melbourne",
"cityCode": "MEL",
"stateCode": "VIC",
"countryCode": "AU",
"countryName": "Australia",
"regionName": "Oceania",
"timeZoneRegionName": "Australia/Sydney",
"localTime": "2015-09-21T10:37:31.611",
"utcOffsetHours": 10,
"latitude": -37.669611,
"longitude": 144.849777,
"elevationFeet": 434,
"classification": 1,
"active": true
}
],
"equipments": [
{
"iata": "787",
"name": "Boeing 787",
"turboProp": false,
"jet": true,
"widebody": true,
"regional": false
}
]
}
}
My desired output at this stage would be for example
[appendix -> airline -> name] - [scheduledFlights -> carrierFsCode][scheduledFlights -> flightNumber]
Jetstar - JQ23
JAL - JL5086
So in a nutshell, to get the desired output, I need to reference the carrierFsCode against the airline name in the appendix for each result. Keep in mind that this example is (for brevity) a low traffic route. JFK to Heathrow for example is much more complex due to the number of flights on that route.
My quite incorrect PHP currently looks like this
$flight_json=get_flight_stats($from,$to,$date);
$flight_stats=$flight_json['scheduledFlights'];
$airlines=$flight_json['appendix']['airlines'];
foreach($flight_stats as $flight_stat)
{
echo $flight_stat['carrierFsCode'].$flight_stat['flightNumber']."<br>";
echo "<br>";
}
foreach($airlines as $airline)
{
echo $airline['name']."<br>";
}
Which returns
JQ23
JL5086
Jetstar
JAL
The get_flight_stats function is used for creating the end point URL, get_file_contents, json_decode then array_map return.
Apologies if this has been asked, just haven't been able to find the right search term and am finding myself a bit stuck.
(EDIT)
Thanks to #jolyonruss, my final code is as follows:
foreach($flight_stats as $flight_stat)
{
/* store the fsCode for this flight */
$fsCode = $flight_stat['carrierFsCode'];
foreach($airlines as $airline)
{
/* test to see if the airline's fsCode matches the flight */
if($airline['fs'] === $fsCode)
{
echo $airline['name']." - ".$fsCode.$flight_stat['flightNumber']."<br>";
}
}
}
Worked a treat.
It looks like you need to nest your for loops, something like this:
$flight_json=get_flight_stats($from,$to,$date);
$flight_stats=$flight_json['scheduledFlights'];
$airlines=$flight_json['appendix']['airlines'];
foreach($flight_stats as $flight_stat)
{
echo $flight_stat['carrierFsCode'].$flight_stat['flightNumber']."<br>";
echo "<br>";
/* store the fsCode for this flight */
$fsCode = $flight_stat['carrierFsCode'];
foreach($airlines as $airline)
{
/* test to see if the airline's fsCode matches the flight */
if($airline['fs'] === $fsCode)
{
echo $airline['name']."<br>";
}
}
}
This is pseudo code, but hopefully you get the idea.

Get data from json array - Undefined index error

Below is json response and I have problems getting shipping_address data.
{
"orders": [{
"created_at": "2015-01-04T02:20:03+01:00",
"financial_status": "paid",
"id": 384536708,
"total_price": "45.00",
"line_items": [{
"fulfillment_service": "manual",
"fulfillment_status": null,
"gift_card": false,
"grams": 0,
"price": "45.00",
"quantity": 1,
"requires_shipping": true,
"taxable": true,
"title": "test",
"vendor": "test",
"name": "test",
"properties": [],
"product_exists": true,
"fulfillable_quantity": 1,
"tax_lines": []
}],
"shipping_address": {
"address1": "Street 20",
"address2": "",
"city": "City",
"company": "",
"country": "USA",
"first_name": "Name",
"last_name": "Surname",
"latitude": 45.000000,
"longitude": 10.000000,
"phone": "",
"province": "",
"zip": "12345",
"name": "Name Surname",
"country_code": "US",
"province_code": null
}
}, [...]
I can get orders with this code:
$content = file_get_contents($url);
$json = json_decode($content, true);
foreach($json['orders'] as $order){
echo "<td>".$order['id']."</td>";
}
But when I try to get shipping_address data like this:
foreach ($json['shipping_address'] as $sa) {
echo "<td>".$sa['name']."</td>";
}
Then i get: Notice: Undefined index: shipping_address and Warning: Invalid argument supplied for foreach()
Am I targeting array wrong?
It should be -
foreach ($json['orders']['shipping_address'] as $sa) {
Try this -
foreach($json['orders'] as $order){
echo "<td>".$order['id']."</td>";
echo "<td>".$order['shipping_address']['name']."</td>";
}
foreach ($json['orders']['shipping_address'] as $sa) {
echo "<td>".$sa['name']."</td>";
}
Try this :
$content = file_get_contents($url);
$json = json_decode($content, true);
foreach($json as $orders){
foreach($orders as $odarr){
foreach($odarr['shipping_address'] as $shipadd){
echo $shipadd['address1'];
}
}
}

Categories