Decoding JSON in PHP can't access the first key - php

I have a PHP script which successfully decodes a JSON string into a PHP object using:
$amount_detail = json_decode($tuitionfee->amount_detail);
when I print it out, this is what I get
stdClass Object
(
[1] => stdClass Object
(
[amount] => 0
[date] => 2023-01-08
[amount_discount] => 55200
[amount_fine] => 0
[description] =>
[collected_by] => Super Admin(356)
[payment_mode] => Cash
[received_by] => 1
[inv_no] => 1
)
[2] => stdClass Object
(
[amount] => 36800
[date] => 2023-01-08
[description] => Collected By: Super Admin
[amount_discount] => 0
[amount_fine] => 0
[payment_mode] => Cash
[received_by] => 1
[inv_no] => 2
)
)
In trying to get the first object [amount_discount], I went further to do this:
if (is_object($amount_detail)) {
foreach ($amount_detail as $amount_detail_key => $amount_detail_value) {
$discount = $amount_detail_value->amount_discount;
}
}
But this is collecting data from the second key [amount_discount].
So instead of getting 55200, I'm getting 0.
How do I get to access data from the first key too?

The $discount variable gets over-written each time loop is executed. So you will always get the last data.
So if you want only the first index value then use current()
$discount = current((Array)$amount_detail_value)->amount_discount;
Output: https://3v4l.org/8Wvqv
Note: In case you want all discount output then in your loop echo the $discount variable.

Related

PHP read first item in object array

I have my code in PHP which is returning this Array of data:
GoCardlessPro\Core\ListResponse Object
(
[records] => Array
(
[0] => GoCardlessPro\Resources\Mandate Object
(
[model_name:protected] => Mandate
[created_at:protected] => 2017-04-01T16:49:09.642Z
[id:protected] => ID001
[links:protected] => stdClass Object
(
[customer_bank_account] => CB001
[creditor] => CR001
[customer] => CU001
)
[metadata:protected] => stdClass Object
(
)
[next_possible_charge_date:protected] => 2017-04-06
[payments_require_approval:protected] =>
[reference:protected] => RE001
[scheme:protected] => bacs
[status:protected] => active
[data:GoCardlessPro\Resources\BaseResource:private] => stdClass Object
(
[id] => 123
[created_at] => 2017-04-01T16:49:09.642Z
[reference] => RE001
[status] => active
[scheme] => bacs
[next_possible_charge_date] => 2017-04-06
[payments_require_approval] =>
[metadata] => stdClass Object
(
)
[links] => stdClass Object
(
[customer_bank_account] => 001
[creditor] => CR001
[customer] => CU001
)
)
[api_response] =>
)
)
)
I want to be able to read the ID of the first item in therecords array.
This data is contained inside a variable called $GC_Mandate;
I have tried these:
echo $GC_Mandate->records->{0}->id;
echo $GC_Mandate->records->0->id;
echo $GC_Mandate->records->[0]->id;
$GC_Mandate = $GC_Mandate->records;
echo $GC_Mandate->{0}->id;
But none will return the data
To get the first record, the syntax you need is $GC_Mandate->records[ 0 ].
However, that object is a GoCardlessPro\Resources\Mandate object and its member id is protected1, so we'd need to know the interface of GoCardlessPro\Resources\Mandate (its public methods1), to know if we can somehow retrieve the value of id.
My guess would be getId(), so the full syntax would become
$GC_Mandate->records[ 0 ]->getId()
But, that's just a guess. You'd have to look into the documentation/class definition of GoCardlessPro\Resources\Mandate, to be sure if you can retrieve id.
Turns out (provided I'm linking to the correct github repository) you can do:
$GC_Mandate->records[ 0 ]->id
since GoCardlessPro\Resources\Mandate extends GoCardlessPro\Resources\BaseResource, which exposes the protected members through GoCardlessPro\Resources\BaseResource::__get()2.
1. visibility in PHP
2. magic methods in PHP
I can't comment so I guess I'll have to post.
You should try to print_r($GC_Mandate); and see what it gives out and then go from there.
Try $GC_Mandate->records[0]->__get('id')
it will return all data ..for perticulat data put this in foreach loop
print_r($GC_Mandate['records']);

Removing elements from an associative array

This post describes how to remove an element of an associative array with Unset i.e unset($array['key1']);
I have this array:
Array
(
[queryLocator] =>
[done] => 1
[records] => Array
(
[0] => stdClass Object
(
[Id] =>
[CreatedDate] => 2016-08-28T14:43:45.000Z
[Leader__c] => GF
[Location__c] => Postbridge
[Service_Date__c] => 2016-09-03
[Service_Time__c] => 14:30
[Service_Type__c] => Baptism
)
)
[size] => 42
[pointer] => 0
[QueryResultsf] => SforceEnterpriseClient Object
(
[sforce:protected] => SoapClient Object
(
[trace] => 1
[compression] => 32
[_encoding] => utf-8
[_features] => 1
[_user_agent] => salesforce-toolkit-php/20.0
[_soap_version] => 1
[sdl] => Resource id #8
[packageVersionHeader:protected] =>
[client_id:protected] =>
)
)
)
I want to delete the key [queryLocator], replace the key [done] with [total], replace the key [records] with [rows] and delete all subsequent keys i.e [size], [pointer] etc.
Using unset, i.e unset($array['queryLocator']); has no effect.
What am I doing wrong ? Thanks.
Here is the code that achieves what I wanted - taking output from a Sales Force query and formatting it as required by a EasyUI datagrid.
//--Get the Sales Force Data
$response = $mySforceConnection->query($query);
//--Encode and decode - for some reason
$data = json_encode((array)$response);
$x = json_decode($data,true);
//--Empty Array
$q = array();
//--Add array element for number records
$q['total'] = $numRecs;
//--Copy the array element from original query with data
$q['rows'] = $x['records'];
//--JSON Encode the new array
$y = json_encode($q);
//--Return the array to Ajax call
echo ($y);
And here's a snippet of the validated JSON..
{
"total":193,
"rows":[
{
"Id":null,
"CreatedDate":"2016-08-28T14:43:45.000Z",
"Leader__c":"GF",
"Location__c":"Postbridge",
"Service_Date__c":"2016-09-03",
"Service_Time__c":"14:30",
"Service_Type__c":"Baptism"
},
{
"Id":null,
"CreatedDate":"2016-08-17T20:43:10.000Z",
"Leader__c":"GF",
"Location__c":"Ashburton",
"Service_Date__c":"2016-09-04",
"Service_Time__c":"08:00",
"Service_Type__c":"HC 2"
},
{
"Id":null,
"CreatedDate":"2016-08-17T20:43:10.000Z",
"Leader__c":"GF",
"Location__c":"Bickington",
"Service_Date__c":"2016-09-04",
"Service_Time__c":"09:00",
"Service_Type__c":"HC 2"
},
{
"Id":null,
"CreatedDate":"2016-08-17T20:43:10.000Z",
"Leader__c":"MC",
"Location__c":"Holne",
"Service_Date__c":"2016-09-04",
"Service_Time__c":"10:30",
"Service_Type__c":"HC 1"
},
I struggled a bit with the array manipulation but it works. Any code improvement suggestions most welcome !

PHP function to update array value where part of array matches other part of array?

Let's say I need to update one of the [status] array values in the returned Array below.
In PHP I will get the array returned below into this variable $taskArray
The only thing I will have is the [taskid] of the Array item I need to modify and the new value for [status] that I would like to change it to.
I am looking for the most efficient way that I can take the array below, find the array that matches my [taskid] and change the [status] to my new status value and then return the complete updated array to a variable so I can pass it back to my database.
I'm really not sure how I can do that based on how the array is setup, I would appreciate any help in doing this please?
Based on this array below, I would like to basically pass in these 2 variable into a function and have the function make the updates mentioned above and return the whole updated array...
function updateTaskStatus($taskId, $newStatus){
// Contains the Array that is shown below this function
$tasksArray;
// Update $tasksArray [status] with the value of $newStatus
// WHERE $taskId is in the SAME array
// RETURN UPDATED $tasksArray
return $tasksArray;
}
// Calling function above would update the [status] to 'completed
// WHERE [taskid] = 4
updateTaskStatus(4, 'Completed');
Array
(
[0] => Array
(
[taskid] => 3
[name] => sdgsdfgdfg
[description] => dfgsdfgsdfg
[status] => In Progress
[priority] => Low
[type] => Magento
)
[1] => Array
(
[taskid] => 4
[name] => Dfgyrty
[description] => rtyrty
[status] => Open
[priority] => Urgent
[type] => Design
)
[2] => Array
(
[taskid] => 9
[name] => yrgrtyerty
[description] => rtyrt6yerty
[status] => Cancelled
[priority] => Urgent
[type] => Magento
)
[3] => Array
(
[taskid] => 9
[name] => ertgsdftg
[description] => dfgsdfg
[status] => Open
[priority] => Medium
[type] => SEO
)
[4] => Array
(
[taskid] => 30
[name] => fghdfgh
[description] => fghdfgh
[status] => In Progress
[priority] => Low
[type] => SEO
)
[5] => Array
(
[taskid] => 1410858495187
[name] => tyrty
[description] => tyrty
[status] => Open
[priority] => Low
[type] => Other
)
)
If I understood your question, the simple answer is to do a loop like this:
function updateTaskStatus($taskId, $newStatus){
global $tasksArray;
foreach($tasksArray as $k => $task)
{
if ($task['taskid'] == $taskId)
{
$tasksArray[$k]['status'] = $newStatus;
break;
}
}
return $tasksArray;
}
Note there is other solution (see php documentation with all array_* functions).
I added global to your code because otherwise this would not work, but using global is something to avoid everytime you can.
The easiest way to do this sort of thing is using a loop.
<?php
function updateTaskStatus($taskId, $newStatus){
// Loop through all the tasks to see if there's a match
foreach ($tasksArray as $id => $task) {
if ($task['taskid'] != $taskId) {
// Mismatch
continue;
}
$tasksArray[$id]['status'] = $newStatus;
}
// RETURN UPDATED $tasksArray
return $tasksArray;
}
You can do it like this:
foreach ($tasksArray as $task)
if ($task['taskid'] == $taskId)
$task['status'] = $newStatus;
Change key to task id and then use something like this
function updateTaskStatus($taskId, $newStatus){
$tasksArray[$taskId]['status'] = $newStatus;
}
updateTaskStatus(4, 'Completed');

Kaltura KalturaMetadataListResponse print_r result

I get the following returned result from a print_r of a variable returned from a $metadataPlugin->metadata->listAction($filter, $pager) function. I am trying to echo out the [xml] piece but can't figure out how to do it.
KalturaMetadataListResponse Object ( [objects] => Array ( [0] => KalturaMetadata Object ( [id] => 1 [partnerId] => 8 [metadataProfileId] => 2 [metadataProfileVersion] => 1 [metadataObjectType] => 1 [objectId] => 0 [version] => 1 [createdAt] => 1353093894 [updatedAt] => 1353093894 [status] => 1 [xml] => 1353049200 ) ) [totalCount] => 1 )
I have tried
echo $result['objects'][0]->xml;
and
echo $result[0]->xml;
with no success.
It looks like it should be
$result->objects[0]->xml
Just remember when looking at print_r or var_dump results that any time you see Object (...) that you will need to use -> to access the property listed for that object.
So in this case, you have a base Object set as $result, which you then need to get the objects property from. That property contains an array. At index 0 of the array, is another Object, which is the Object where your xml property resides.

foreach loops & stdclass objects

I've seen similar questions on here but I can't seem to apply the solutions to my problem. I have a variable called $results which I got from an API. I'll change the proper nouns so as to protect my work's customers:
stdClass Object
(
[out] => stdClass Object
(
[count] => 2
[transactions] => stdClass Object
(
[RealTimeCommissionDataV2] => Array
(
[0] => stdClass Object
(
[adId] => 12345678
[advertiserId] => 123456789
[advertiserName] => Chuck E. Cheese, inc.
[commissionAmount] => 50
[country] => US
[details] => stdClass Object
(
)
[eventDate] => 2009-11-16T09:44:25-08:00
[orderId] => X-XXXXXXXXXX
[saleAmount] => 0
[sid] => 123456789
[websiteId] => 2211944
)
[1] => stdClass Object
(
[adId] => 987654321
[advertiserId] => 12345
[advertiserName] => Chorizon Wireless.
[commissionAmount] => 50
[country] => US
[details] => stdClass Object
(
)
[eventDate] => 2009-11-16T09:58:40-08:00
[orderId] => X-CXXXXXX
[saleAmount] => 0
[sid] => 61-122112
[websiteId] => 1111922
)
)
)
)
)
I shortened it to two entries here but the number of entries will vary, it's the result of a check for transactions in the past hour, there may sometimes be only one and sometimes as many as a dozen.
I want to assign these entries to variables like websiteId1 websiteId2 etc. I know I need to do a foreach loop but can't seem to figure it out. How can I write it so that I get the "[details]" as well?
foreach ($results->out->transactions->RealTimeCommissionDataV2 AS $commissionData) {
// you can access the commissionData objects now, i.e.:
$commissionData->adId;
$commissionData->details;
}
<?
foreach ($result->out->transactions->RealTimeCommissionDataV2 as $item)
{
// do somthing with each item.
print_r($item);
// or the details array
$num_details = sizeof($item->details)
}
I think this is what you want.
EDIT
Updated based on some notes in the documentation. Specifically, these two
a numerically indexed array will not
produce results unless you use
EXTR_PREFIX_ALL or
EXTR_PREFIX_INVALID.
Prefixes are automatically separated
from the array key by an underscore
character.
echo extract( $results->out->transactions->RealTimeCommissionDataV2, EXTR_PREFIX_ALL, 'websiteId' );
// test the extract
print_r( $websiteId_0 );

Categories