echo "<pre>"; print_r($data); echo "</pre>";
Gives following output:
$stdClass Object
(
[cartName] => AngularStore
[clearCart] =>
[checkoutParameters] => stdClass Object
(
)
[items] => Array
(
[0] => stdClass Object
(
[sku] => 01
[name] => Product 1
[price] => 600
[quantity] => 1
[stock] => 5
[scheme] => Array
(
[0] => stdClass Object
(
[name] => offerAB
[desc] => Description on the scheme
[no] => 3
[$$hashKey] => 01O
[checked] => 1
)
[1] => stdClass Object
(
[name] => offerXY
[desc] => Description on the scheme
[no] => 5
[$$hashKey] => 01P
)
[2] => stdClass Object
(
[name] => OfferPQ
[desc] => Description on the scheme
[no] => 2
[$$hashKey] => 01Q
[checked] => 1
)
[3] => stdClass Object
(
[name] => OfferLM
[desc] => Description on the scheme
[no] => 4
[$$hashKey] => 01R
)
)
[$$hashKey] => 05V
)
[1] => stdClass Object
(
[sku] => 02
[name] => Product 2
[price] => 500
[quantity] => 1
[stock] => 400
[scheme] => Array
(
[0] => stdClass Object
(
[name] => offerAB
[desc] => Description on the scheme
[no] => 6
[$$hashKey] => 01W
)
[1] => stdClass Object
(
[name] => offerXY
[desc] => Description on the scheme
[no] => 7
[$$hashKey] => 01X
)
[2] => stdClass Object
(
[name] => OfferPQ
[desc] => Description on the scheme
[no] => 3
[$$hashKey] => 01Y
)
[3] => stdClass Object
(
[name] => OfferLM
[desc] => Description on the scheme
[no] => 8
[$$hashKey] => 01Z
)
)
[$$hashKey] => 05W
)
)
[qty] => 3
)
I want to print value of sku , name, price using foreach loop
Since i m new to it i first started printing a single value
echo $data->items->arr[0]->sku;
Notice: Trying to get property of non-object getting this error
but i want to print the values in foreach please help!
Items is a property of the main object, and in itself is an array. This is what you're after:
foreach($data->items as $d) {
echo $d->name, '<br />', $d->sku, '<br />', $d->price;
}
If you want to access one of those element without a loop, you need to provide the array index, for example:
echo $data->items[0]->name
the easy way for you is convert object to array
function array2object($array) {
if (is_array($array)) {
$obj = new StdClass();
foreach ($array as $key => $val){
$obj->$key = $val;
}
}
else { $obj = $array; }
return $obj;
}
function object2array($object) {
if (is_object($object)) {
foreach ($object as $key => $value) {
$array[$key] = $value;
}
}
else {
$array = $object;
}
return $array;
}
// example:
$array = array('foo' => 'bar', 'one' => 'two', 'three' => 'four');
$obj = array2object($array);
print $obj->one; // output's "two"
$arr = object2array($obj);
print $arr['foo']; // output's bar
foreach($data['items'] as $item) {
echo $item['sku'].PHP_EOL
echo $item['name'].PHP_EOL
echo $item['price'].PHP_EOL;
}
Related
I am working with soap responses that contain nested wrappers and whose child(ren) have nested properties.
I am trying to flatten these response to:
remove the wrappers
flatten the children
maintain the individual children (dimensions)
I am currently working with the following that achieves #1 and #3 however it does not flatten the inner children. Note that $this->response is converted from a stdClass to Array before being flattened.
How can I also flatten down the inner nested child elements?
private function toArray()
{
$this->response = json_decode(json_encode($this->response), true);
return $this;
}
private function flatten($array = null)
{
if (is_null($array)) {
$array = $this->response;
}
if (is_array($array)) {
foreach ($array as $k => $v) {
if (count($v) == 1 && is_array($v)) {
return $this->flatten($v);
}
if (isset($v[0])) {
$this->response = $v;
return $this;
}
unset($this->response);
$this->response[] = $v;
return $this;
}
}
}
...which will transform this:
stdClass Object
(
[ArrayOfDevice] => stdClass Object
(
[Device] => Array
(
[0] => stdClass Object
(
[NamedElement] => stdClass Object
(
[Element] => stdClass Object
(
[ElementType] => DEVICE
[id] => Device1ID
)
[name] => Device1
)
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => stdClass Object
(
[NamedElement] => stdClass Object
(
[Element] => stdClass Object
(
[ElementType] => DEVICE
[id] => Device2ID
)
[name] => Device2
)
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
)
)
...to this:
Array
(
[0] => Array
(
[NamedElement] => Array
(
[Element] => Array
(
[ElementType] => DEVICE
[id] => Device1ID
)
[name] => Device1
)
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => Array
(
[NamedElement] => Array
(
[Element] => Array
(
[ElementType] => DEVICE
[id] => Device2ID
)
[name] => Device2
)
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
...but I'd prefer:
Array
(
[0] => Array
(
[ElementType] => DEVICE
[id] => Device1ID
[name] => Device1
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => Array
(
[ElementType] => DEVICE
[id] => Device2ID
[name] => Device2
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
...and in the case of a single item being returned, this:
stdClass Object
(
[ArrayOfAlarm] => stdClass Object
(
[Alarm] => stdClass Object
(
[Element] => stdClass Object
(
[ElementType] => ALARM
[id] => Alarm1ID
)
[activeTime] =>
[AlarmSeverity] =>
[AlarmState] =>
[description] =>
[deviceID] =>
[recommendedAction] =>
[resolvedTime] =>
[sensorID] =>
)
)
)
...to this:
Array
(
[0] => Array
(
[Element] => Array
(
[ElementType] => ALARM
[id] => Alarm1ID
)
[activeTime] =>
[AlarmSeverity] =>
[AlarmState] =>
[description] =>
[deviceID] =>
[recommendedAction] =>
[resolvedTime] =>
[sensorID] =>
)
)
...but I'd prefer:
Array
(
[0] => Array
(
[ElementType] => ALARM
[id] => Alarm1ID
[activeTime] =>
[AlarmSeverity] =>
[AlarmState] =>
[description] =>
[deviceID] =>
[recommendedAction] =>
[resolvedTime] =>
[sensorID] =>
)
)
You can flatten a single of your items with the following function:
function flatten_item($array)
{
$result = [];
foreach ($array as $k => $v) {
if (is_array($v)) {
$result = array_merge($result, $this->flatten_item($v));
} else {
$result[$k] = $v;
}
}
return $result;
}
When you have an array of results, you can pass this function as the callback to array_map. Only the relevant portion of the code:
if (isset($v[0])) {
$this->response = array_map([$this, 'flatten_item'], $v);
return $this;
}
// Convert single result to an array
$this->response = [$this->flatten_item($v)];
return $this;
Since the response (so far) always has the same structure, you could extract the payload without using recursion, which allows you to also remove the foreach in the flatten function:
function flatten()
{
// Remove outer wrappers [ArrayOfX][X] by extracting the value
$payload = current(current($this->response));
if (isset($payload[0])) {
$this->response = array_map([$this, 'flatten_item'], $payload);
} else {
$this->response = [$this->flatten_item($payload)];
}
return $this;
}
The function found here does just what you want, with a slight modification (commented out concatination of parent keys): https://gist.github.com/kohnmd/11197713#gistcomment-1895523
function flattenWithKeys(array $array, $childPrefix = '.', $root = '', $result = array()) {
foreach($array as $k => $v) {
if(is_array($v) || is_object($v)) $result = flattenWithKeys( (array) $v, $childPrefix, $root . $k . $childPrefix, $result);
else $result[ /*$root .*/ $k ] = $v;
}
return $result;
}
Letting $object equal your provided object, use as follows:
$array = json_decode(json_encode($object), true);
$result =[];
foreach( $array['ArrayOfDevice']['Device'] as $key => $value ){
$result[$key] = flattenWithKeys($value);
}
print_r($result);
Output:
Array
(
[0] => Array
(
[ElementType] => DEVICE
[id] => Device1ID
[hostName] => Device1.hostname
[ipAddress] => Device1.ip
[location] => location1
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 123456789
)
[1] => Array
(
[ElementType] => DEVICE
[id] => Device2ID
[name] => Device2
[hostName] => Device2.hostname
[ipAddress] => Device2.ip
[location] => location2
[modelName] =>
[modelNumber] =>
[parentID] => xxxYYY
[serialNumber] => 987654321
)
)
See it run here: http://sandbox.onlinephpfunctions.com/code/851e93389b993a0e44c1e916291dc444f47047d3
I am trying to print a json array into its values I have the following array after json decode and i need to print it in a loop as it has many items.
For e.g i have to print the value firstName, lastName ,how will i print it.
stdClass Object ( [content] => Array ( [0] => stdClass Object ( [id] => 5 [firstName] => Ali [lastName] => S [profilePhotoUrl] => https://prn-spe-images.s3-ap-southeast-1.amazonaws.com/user-profiles/5.jpg [handle] => aliya ) [1] => stdClass Object ( [id] => 69 [handle] => hhtc ) ) [last] => 1 [totalPages] => 1 [totalElements] => 2 [numberOfElements] => 2 [first] => 1 [sort] => [size] => 10 [number] => 0 )
Sample code i have done :
$arrayl = gettviewers($post->id,10);
foreach($arrayl as $valuel) {
print $value1->content->firstName;
}
But it is not printing any value.
### Full working code from the below answers: ###
Helper file:
####### --- Get live viwers list for each broadcast --- ########
if ( ! function_exists('gettviewers'))
{
function gettviewers($broId,$size){
$CI =& get_instance();
$url = API_SERVER.'broadcasts/public/'.$broId.'/top-viewers?size='.$size;
$json = json_decode(file_get_contents($url), true);
return $json;
}
}
In the view:
$arrayl = gettviewers($post->id, WI_LIVEUSERSIZE);
foreach($arrayl as $value1)
{
print $value1[0][firstName];
}
Foreach 'takes' every element of a object or an array. So when you do foreach your $value1 isn't
stdClass Object ( [content] => Array ( [0] => stdClass Object ( [id] => 5 [firstName] => Ali [lastName] => S [profilePhotoUrl] => https://prn-spe-images.s3-ap-southeast-1.amazonaws.com/user-profiles/5.jpg [handle] => aliya ) [1] => stdClass Object ( [id] => 69 [handle] => hhtc ) ) [last] => 1 [totalPages] => 1 [totalElements] => 2 [numberOfElements] => 2 [first] => 1 [sort] => [size] => 10 [number] => 0 )
but is
[content] => Array ( [0] => stdClass Object ( [id] => 5 [firstName] => Ali [lastName] => S [profilePhotoUrl] => https://prn-spe-images.s3-ap-southeast-1.amazonaws.com/user-profiles/5.jpg [handle] => aliya ) [1] => stdClass Object ( [id] => 69 [handle] => hhtc ) ) [last] => 1 [totalPages] => 1 [totalElements] => 2 [numberOfElements] => 2 [first] => 1 [sort] => [size] => 10 [number] => 0
So your $value1 is already [content]. Also you should notice that [content] is an array so you have to do
$arrayl = gettviewers($post->id,10);
foreach($arrayl as $valuel) {
print $value1[0]->firstName;
}
or use second foreach loop inside the first one.
You can achieve this using json_decode
json_decode converts a valid JSON to a stdClass-Object.
Try this:
$arrayl = json_decode(gettviewers($post->id, 10));
foreach($arrayl as $value1)
{
print $value1->content->firstName;
}
try this
$arrayl = gettviewers($post->id,10);
if (is_object($arrayl)) {
// Gets the properties of the given object
// with get_object_vars function
$arrayl = get_object_vars($arrayl);
}
if (is_array($arrayl)) {
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
$arrayl = array_map(__FUNCTION__, $arrayl);
}
else {
// Return array
return $arrayl;
}
var_dump($arrayl) or print_r($arrayl);
or
foreach($arrayl as $key=>$val){
echo $val->content[$key]
}
To print json_encoded array do this
$array=json_decode($data,true); //data is your json_encoded data
foreach($array as $key=>$value)
{
echo $key . ' ' . $value . PHP_EOL;
}
or just do
print_r($array);
after decoding it.
I have an array like this on php :
echo "<pre>";
print_r($header_item);
The result is :
Array
(
[0] => stdClass Object
(
[NO_INSPECTION] => 47
[ID_CONDITION] => 1
[NAMA_CONDITION] => DIRTY
)
[1] => stdClass Object
(
[NO_INSPECTION] => 47
[ID_CONDITION] => 2
[NAMA_CONDITION] => DAMAGE
)
[2] => stdClass Object
(
[NO_INSPECTION] =>
[ID_CONDITION] =>
[NAMA_CONDITION] => CLEAN
)
[3] => stdClass Object
(
[NO_INSPECTION] =>
[ID_CONDITION] =>
[NAMA_CONDITION] => OFF HIRE
)
)
I have case like this, this array will be separated into two new array object based even and odds index. So I write like this :
<?php
$odd = array();
$even = array();
$breakrow = 0;
foreach ($header_item as $v) {
if ($breakrow % 2 == 0) {
array_push($even, $v->NO_INSPECTION);
array_push($even, $v->ID_CONDITION);
array_push($even, $v->NAMA_CONDITION);
} else {
array_push($odd, $v->NO_INSPECTION);
array_push($odd, $v->ID_CONDITION);
array_push($odd, $v->NAMA_CONDITION);
}
$breakrow++;
}
?>
But I got those new arrays like this :
echo "<pre>";
print_r($even);
echo "<br>";
echo "<pre>";
print_r($odd);
Array
(
[0] => 47
[1] => 1
[2] => DIRTY
[3] =>
[4] =>
[5] => CLEAN
)
Array
(
[0] => 47
[1] => 2
[2] => DAMAGE
[3] =>
[4] =>
[5] => OFF HIRE
)
How can I make like this :
Array
(
[0] => stdClass Object
(
[NO_INSPECTION] => 47
[ID_CONDITION] => 1
[NAMA_CONDITION] => DIRTY
)
[1] => stdClass Object
(
[NO_INSPECTION] =>
[ID_CONDITION] =>
[NAMA_CONDITION] => CLEAN
)
AND :
Array
(
[0] => stdClass Object
(
[NO_INSPECTION] => 47
[ID_CONDITION] => 2
[NAMA_CONDITION] => DAMAGE
)
[1] => stdClass Object
(
[NO_INSPECTION] =>
[ID_CONDITION] =>
[NAMA_CONDITION] => OFF HIRE
)
You can achieve this using array_walk and a simple test of even vs. odd on the key.
$header_item = [
0 => 'zero',
1 => 'one',
2 => 'two',
3 => 'three',
4 => 'four',
5 => 'five',
6 => 'six',
7 => 'seven'
];
$odd = array();$even = array();
array_walk($header_item,function($value,$key) use(&$odd,&$even){
if ($key%2==0) {
$even[]=$value;
}
else{
$odd[]=$value;
}
});
print_r($even);
print_r($odd);
Will output
Array
(
[0] => zero
[1] => two
[2] => four
[3] => six
)
Array
(
[0] => one
[1] => three
[2] => five
[3] => seven
)
Try this one :-
$odd = array();
$even = array();
$breakrow = 0;
foreach ($header_item as $v) {
if ($breakrow % 2 == 0) {
$even[] = $v;
} else {
$odd[] = $v;
}
$breakrow++;
}
echo '<pre>'; print_r($even).'<br>';
echo '<pre>'; print_r($odd).'<br>';
output:-
Array
(
[0] => Array
(
[NO_INSPECTION] => 47
[ID_CONDITION] => 1
[NAMA_CONDITION] => DIRTY
)
[1] => Array
(
[NO_INSPECTION] =>
[ID_CONDITION] =>
[NAMA_CONDITION] => CLEAN
)
)
Array
(
[0] => Array
(
[NO_INSPECTION] => 47
[ID_CONDITION] => 2
[NAMA_CONDITION] => DAMAGE
)
[1] => Array
(
[NO_INSPECTION] =>
[ID_CONDITION] =>
[NAMA_CONDITION] => OFF HIRE
)
)
I want to merge the 2 arrays of objects based on the 'id' field of Array1 and the 'itemVendorCode' of Array2. I also wanted to remove from the resulting arrays of object anything that didn't match.
Array1:
Array
(
[0] => stdClass Object
(
[id] => 10-423-1176
[qty] => 2
[price] => 12.6
)
[1] => stdClass Object
(
[id] => 89-575-2354
[qty] => 24
[price] => 230.35
)
[2] => stdClass Object
(
[id] => 89-605-1250
[qty] => 2
[price] => 230.35
)
)
Array2:
Array
(
[0] => Item Object
(
[internalId] => 14062
[itemVendorCode] => 89-605-1250
)
[1] => Item Object
(
[internalId] => 33806
[itemVendorCode] => 89-575-2354
)
[2] => Item Object
(
[internalId] => 64126
[itemVendorCode] => 26-295-1006
)
)
I was able to solve this by this code:
$indexed = array();
foreach($itemsArray as $value) {
$indexed[$value->itemVendorCode] = $value;
}
$results = array();
foreach($vendorItems as $obj) {
$value = $indexed[$obj->id];
if (isset($value)) {
foreach($value as $name => $val) {
$obj->$name = $val;
array_push($results, $obj);
}
}
}
print_r($results);
credits to the original poster. I just modified it a bit,
I was able to get the result like this:
Array
(
[0] => stdClass Object
(
[id] => 10-423-1176
[qty] => 2
[price] => 12.6
[internalId] => 2035
[itemVendorCode] => 10-423-1176
)
[1] => stdClass Object
(
[id] => 10-423-1176
[qty] => 2
[price] => 12.6
[internalId] => 2035
[itemVendorCode] => 10-423-1176
)
[2] => stdClass Object
(
[id] => 14-102-1010
[qty] => 16
[price] => 3.2
[internalId] => 57033
[itemVendorCode] => 14-102-1010
)
)
I think you will have to use array_map function which provides you a callback function to execute on array(s).
In the callback function:
- declare your array1
- foreach the second array
- set an if statement to check that the current iteration with the id value matches the itemVendorCode of the array2 and return it
something like this:
// You have to specify to PHP to use a local copy of your $array2 to works with it into your callback
$cb = function ($obj1) use ($array2)
{
// you foreach this array
foreach ($array2 as $obj2) {
// if the value of id matches itemVendorCode
if ($obj1->id === $obj2->itemVendorCode) {
// you return the id
return $obj->id;
}
}
};
// this function will fill a new array with all returned data
$mergedArray = array_map($cb, $array1);
This code is a sample but doesn't provide you, your needled solution, try to update it to do what you exactly want ;)
I have an array that looks like this:
$cars = array (
array(
'a' => 'audi',
'b' => 'a4'),
array(
'a' => 'peugeot',
'b' => '306'),
array(
'a' => 'audi',
'b' => 'a4'),
array(
'a' => 'audi',
'b' => 'a5'),
array(
'a' => 'peugeot',
'b' => '106'),
array(
'a' => 'peugeot',
'b' => '106'),
);
I need to order arrays like this to (id is the same as name):
name => audi
id=> audi
data => a4 => 2
a5 => 1
name => peugeot
id=> peugeot
data => 306 => 1
106 => 2
So the car brands need to be grouped an the car types counted.
I already have this code; but that is only for the group part and the count part is missing.
function mergeAndOrder($data){
// set group arrays
$i = 0; $group1 = array();
// loop trough array
$array = array(); $array2 = array();
if($data != null){
foreach($data AS $row){
// search and order level1
$search = array_search($row->a,$group1);
// this object is not found
if(is_int($search) == false){
$group1[$i] = $row->a;
$array[$i]['id'] = $row->a;
$array[$i]['name'] = $row->a;
$array[$i]['data'] = array();
$i++;
}
}
}
return $array;
}
Does somebody know an solution for this case? Thanks!
--- INPUT (part of) ---
a = lease company in this case
Array
(
[0] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
[1] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
[2] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
[3] => stdClass Object
(
[b] => AUDI
[a] => LPN
)
--- OUTPUT (part of) ---
Array
(
[0] => Array
(
[id] => LPN
[name] => LPN
[data] => Array
(
)
)
[1] => Array
(
[id] => ARV
[name] => ARV
[data] => Array
(
)
)
[2] => Array
(
[id] => ARVB
[name] => ARVB
[data] => Array
(
)
)
[3] => Array
(
[id] => LPD
[name] => LPD
[data] => Array
(
)
)
)
Array
(
[0] => Array
(
[id] => LPN
[name] => LPN
[data] => Array
(
)
)
[1] => Array
(
[id] => ARV
[name] => ARV
[data] => Array
(
)
)
[2] => Array
(
[id] => ARVB
[name] => ARVB
[data] => Array
(
)
)
If I understand your question correctly, this should do what you want.
function mergeAndOrder ($data) {
$output = array();
foreach ($data as $item) {
$id = $item->a;
$value = $item->b;
if (!array_key_exists($id, $output)) {
$output[$id] = array('id' => $id, 'name' => $id, 'data' => array());
}
if (!array_key_exists($value, $output[$id]['data'])) {
$output[$id]['data'][$value] = 0;
}
$output[$id]['data'][$value]++;
}
// Order by name element
uasort($output, function ($a, $b) {
return strcasecmp($a['name'], $b['name']);
});
return $output;
}
Output:
Array
(
[audi] => Array
(
[id] => audi
[name] => audi
[data] => Array
(
[a4] => 2
[a5] => 1
)
)
[peugeot] => Array
(
[id] => peugeot
[name] => peugeot
[data] => Array
(
[306] => 1
[106] => 2
)
)
)