PHP foreach loop breaking with sub object - php

I'm trying to access third party api which gives me object and sub object, for example:
stdClass Object
(
[truncated] =>
[text] => "some text"
[user] => stdClass Object
(
[count] => 9370
[comments_enabled] => yes
When I try and loop through the object with the following code I get an error at the start of sub-object 'user'. Can anyone help me either 1) iterate through the sub-object, or 2) block the sub-object from the loop.
The code:
$test = $s[0];
$obj = new ArrayObject($test);
foreach ($obj as $data => $name) {
print $data . ' - ' . $name . '<br />';
}
thanks

It's because the 'user' field is an object, so you need to separately run through each field within that object
function iterateObject($obj, $name='') {
//for each element
foreach ($obj as $key=>$val) {
$myName = ($name !='') ? "$name.$key" : $key;
//if type of the element is an object or array
if ( is_object($val) || is_array($val) ) {
//if so, iterate through its properties
iterateObject($val, $myName);
}
//otherwise output name/ value combination
else {
print "$myName - $val <br/>";
}
}
}
$test = $s[0];
$obj = new ArrayObject( $test );
iterateObject( $obj );
Will output
truncated -
text - some text
user.count - 9370
user.comments_enabled - yes

This will iterate through a tree of objects and print key - value pairs...
printObject($test);
function printObject($obj) {
foreach (get_object_vars($obj) as $field => $value) {
if (is_object($value)) {
printObject($value);
} else {
print $field . ' - ' . $value . '<br />';
}
}
}

<?php
function traceObject($object) {
foreach ($object as $data => $name) {
if (is_object($name)) {
traceObject($name);
} else {
echo $data . ' - ' . $name .'<br />';
}
}
}

Related

Looping into a multidimensional array with PHP

I've got this array:
Array
(
[0] => Array
(
[name] => System
[order] => 1
[icon] => stats.svg
[0] => Array
(
[title] => Multilingual
)
[1] => Array
(
[title] => Coloring
)
[2] => Array
(
[title] => Team work
)
[3] => Array
(
[title] => Tutorials
)
)
)
I want to loop into this to show the section name and after all the features containing in the following array.
So, this is what I made:
foreach ($features as $feature => $info) {
echo '
'.$info['name'].'
<ul class="menu-vertical bullets">
';
foreach (array_values($info) as $i => $key) {
echo '
<li>'.$key['title'].'</li>
';
}
echo '
</ul>
';
}
It works except for the first third <li> where I have the first char of name, order and icon value.
Do you know why ?
Thanks.
array_values return value of array so for info values is name, order, icon, 0, 1, ...
Your values foreach is wrong if you just want print title you can use:
foreach ($features as $feature => $info) {
echo '
'.$info['name'].'
<ul class="menu-vertical bullets">
';
//Remove some keys from info array
$removeKeys = array('name', 'order', 'icon');
$arr = $info;
foreach($removeKeys as $key) {
unset($arr[$key]);
}
foreach (array_values($arr) as $i => $key) {
echo '
<li>'.$key['title'].'</li>
';
}
echo '
</ul>
';
}
In php, array_values means all the values of the array. So array_values($info) is array($info['name'], $info['order'], $info['icon'], $info[0], $info[1], $info[2], $info[3])
in your example, you can skip the non-integer keys of the $info to get your titles:
<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info[] = array('title'=>'Multilingual');
$info[] = array('title'=>'Coloring');
$features[] = $info;
foreach ($features as $feature => $info) {
echo $info['name'] . PHP_EOL;
echo '<ul class="menu-vertical bullets">' . PHP_EOL;
foreach ($info as $k => $item) {
if(!is_int($k)) continue;
echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
}
echo '</ul>' . PHP_EOL;
}
BUT, your original data structure is not well designed and hard to use. For a better design, you can consider the following code, move your items to a sub array of $info:
<?php
$features = array();
$info = array();
$info['name'] = 'System';
$info['order'] = 1;
$info['icon'] = 'stats.svg';
$info['items'] = array();
$info['items'][] = array('title'=>'Multilingual');
$info['items'][] = array('title'=>'Coloring');
$features[] = $info;
foreach ($features as $feature => $info) {
echo $info['name'] . PHP_EOL;
echo '<ul class="menu-vertical bullets">' . PHP_EOL;
foreach ($info['items'] as $item) {
echo '<li>' . $item['title'] . '</li>' . PHP_EOL;
}
echo '</ul>' . PHP_EOL;
}
Sample output of the two demos:
System
<ul class="menu-vertical bullets">
<li>Multilingual</li>
<li>Coloring</li>
</ul>
It works except for the first third li where I have the first char of name, order and icon value. Do you know why ?
Why you see first chars of the values of 'name', 'order', 'icon'? Let see how PHP works.
Take the first loop as an example: foreach (array_values($info) as $i => $key)
Then $i == 0, $key == 'System'
We know that $key[0] == 'S', $key[1] == 'y', $key[2] == 's', etc.
Then you try to access $key['title'], but the string 'title' is not valid as a string offset, so it is converted to an integer by PHP: intval('title') == 0.
Then $key['title'] == $key[intval('title')] == 'S'
That's what you see.
array_value() returns the values of the array, here you will get the value of the array $info and what I understand is that is not what you need. See details for array_value().
You can check if the key for the $info is an integer. if yes, echo the title. Give this a try.
foreach ($features as $feature => $info) {
echo $info['name'].'<ul class="menu-vertical bullets">';
foreach ($info as $key => $value) {
if (is_int($key)) {
echo '<li>'.$key['title'].'</li>';
}
}
echo '</ul>';
}

How can I access individual values in an associative array in PHP?

I am pulling elements from a standard class object into an assoc array like so:
$array = $subjects;
foreach ( $array as $subject ) {
foreach ( $subject as $prop => $val ) {
if ( $val !== '' ) {
echo $prop . ' = ' . $val;
echo "<br>";
}
}
}
I get the result I expect from above, except what I'd like to do is echo out individual values into a table.
When I do this:
echo $subject['day1'];
I get this: "Cannot use object of type stdClass as array."
Where am I going wrong? Thanks in advance.
If it's using StdClass you'll need to do this:
$subject->day1
If you want to convert it to an array, have a look at this question: php stdClass to array
You are trying to iterate over the $array and $array is still an object. Use this:
$vars = get_object_vars($subjects);
to get assoc. array from the object $subjects. Then go:
foreach ($vars as $name => $value) {
echo $name . "=" . $value;
echo "<br>";
}

Looping through a JSON in PHP

I'm trying to loop through a JSON that I post to my PHP backend. The JSON looks like this:
[
{
"number":"5613106"
},
{
"number":"56131064"
},
{
"number":"56131063"
}
]
I post it from Postman like so:
I want to be able to print each number that I've posted individually using
echo $number;
Right now when I use the following it just prints the last number:
$number = $json['number'];
echo $number;
My function:
public function check_users_post()
{
$json = $this->request->body;
print_r($json);
$this->response($json, REST_Controller::HTTP_OK);
}
The output:
Array
(
[0] => Array
(
[number] => 5613106
)
[1] => Array
(
[number] => 56131064
)
[2] => Array
(
[number] => 56131063
)
)
Hope this generic iterator will help you.
$jsonIterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator(json_decode($json, TRUE)),
RecursiveIteratorIterator::SELF_FIRST);
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
echo "$key:\n";
} else {
echo "$key => $val\n";
}
}
Use
json_decode()
PHP built in function for decoding json back to PHP variable or array and then loop through each index and print number.
Got it done like this:
public function check_users_post()
{
$json = $this->request->body;
$jsonIterator = new RecursiveIteratorIterator(
new RecursiveArrayIterator($json),
RecursiveIteratorIterator::SELF_FIRST);
$phone_numbers = "";
foreach ($jsonIterator as $key => $val) {
if(is_array($val)) {
} else {
$phone_numbers = "$phone_numbers" . ", " . "$val";
}
}
$phone_numbers = substr($phone_numbers, 2);
$phone_numbers = "(" . $phone_numbers . ")";
$query = $this->db->query("SELECT * FROM users WHERE user_number in $phone_numbers;");
$result = $query->result();
$this->response($result, REST_Controller::HTTP_OK);
if (mysql_num_rows($result)==0) {
$data = [ 'message' => 'No users returned'];
$this->response($data, REST_Controller::HTTP_BAD_REQUEST);
} else {
$this->response($result, REST_Controller::HTTP_OK);
}
}
Description
First stringify your JSON, than use JSON_DECODE() function which gives you the array afterwards iterate on this array using foreach loop which will give you the each key which you want to echo.
Code
$str = '[
{
"number":"5613106"
},
{
"number":"56131064"
},
{
"number":"56131063"
}
]';
$array = json_decode($str, true);
echo "<pre>";
foreach ($array as $key => $key_value) { // then loop through it
echo "<br>";
echo $array[$key]['number'];
echo "<br>";
}
Output
5613106
56131064
56131063

array result using foreach statement display in json in php

I am getting the result from web service SOAP client. I have created an array to get the result and display it using json format. I am getting few of my results properly. I have SerialEquipment parameter which is array and i need to get the result using foreach loop. I am doing an mistake there. I dont know how can i assign my $vehiclResult array in this for each statement. So that all the results at last i will collect and display using json using vehicleResult array.My mistake is in the foreach loop.
structure for SerialEquipment parameters:
Code:
$vehicle = getVehicleValuation();
$Serial=$vehicle['SerialEquipment'];
$vehiclResult = array(
'WE_Number' => $vehicle['WE Number'] ."<br>",
'Vehicle Type'=> $vehicle['Vehicle Type'] . "<br>",
'HSN' => $vehicle['HSN'] . "<br>",
'TSN' => $vehicle['TSN'] . "<br>"
);
foreach($Serial as $key => $obj) {
if(!isset($vehiclResult[$key]))
$vehiclResult[$key] = array();
$vehiclResult[$key]['SerialEquipment'] = $key. "<br>";
$vehiclResult[$key]['Code'] = $obj->Code. "<br>";
$vehiclResult[$key]['Desc Short'] = $obj->Desc_Short. "<br>";
$vehiclResult[$key]['Desc Long'] = $obj->Desc_Long. "<br>";
foreach($obj->Esaco as $key2 => $obj2) {
if($obj2->EsacoMainGroupCode === null){
// doesn't contain Esaco
continue;
}
else{
if(!isset($vehiclResult[$key][$key2]))
$vehiclResult[$key][$key2] = array();
$vehiclResult[$key][$key2]['esaco'] = $key2. "<br>";
$vehiclResult[$key][$key2]['EsacoMainGroupCode'] = $obj2->EsacoMainGroupCode. "<br>";
$vehiclResult[$key][$key2]['EsacoMainGroupDesc'] = $obj2->EsacoMainGroupDesc. "<br>";
$vehiclResult[$key][$key2]['EsacoSubGroupCode'] = $obj2->EsacoSubGroupCode. "<br>";
$vehiclResult[$key][$key2]['EsacoSubGroupDesc'] = utf8_decode($obj2->EsacoSubGroupDesc). "<br>";
$vehiclResult[$key][$key2]['EsacoGroupCode'] = $obj2->EsacoGroupCode. "<br>";
$vehiclResult[$key][$key2]['EsacoGroupDesc'] = utf8_decode($obj2->EsacoGroupDesc). "<br>";
}
}
}
$result = array(
'vehicle' => $vehiclResult
);
echo json_encode($result);
die();
}
You need to check if your array have the key so:
if(!isset($vehiclResult[$key]))
if not, you need to create it:
$vehiclResult[$key] = array(); // as an array
Also, you don't really need to make a description of your "item". You can Parse your JSON on the result page to output some text.
You can do something like.
Do something like:
foreach($Serial as $key => $obj) {
if(!isset($vehiclResult[$key]))
$vehiclResult[$key] = array();
$vehiclResult[$key]['serial'] = $key;
$vehiclResult[$key]['code'] = $obj->Code;
$vehiclResult[$key]['short_desc'] = $obj->Desc_Short;
$vehiclResult[$key]['long_desc'] = $obj->Desc_Long;
foreach($obj->Esaco as $key2 => $obj2) {
if($obj2->EsacoMainGroupCode === null){
// doesn't contain Esaco
continue;
}
else{
if(!isset($vehiclResult[$key][$key2]))
$vehiclResult[$key][$key2] = array();
$vehiclResult[$key][$key2]['esaco'] = $key2;
$vehiclResult[$key][$key2]['EsacoMainGroupCode'] = $obj2->EsacoMainGroupCode;
$vehiclResult[$key][$key2]['EsacoMainGroupDesc'] = $obj2->EsacoMainGroupDesc;
$vehiclResult[$key][$key2]['EsacoSubGroupCode'] = $obj2->EsacoSubGroupCode;
$vehiclResult[$key][$key2]['EsacoSubGroupDesc'] = utf8_decode($obj2->EsacoSubGroupDesc);
$vehiclResult[$key][$key2]['EsacoGroupCode'] = $obj2->EsacoGroupCode;
$vehiclResult[$key][$key2]['EsacoGroupDesc'] = utf8_decode($obj2->EsacoGroupDesc);
}
}
}
$result = array(
'vehicle' => $vehiclResult
);
echo json_encode($result);
die();
If you would keep your "text" and your <br> code, do the samething but add what you want to output after the "="
EDIT
** A HAVE CHANGE THE CODE PREVIOUSLY..
if you want to test your $vehiclResult, try something like:
foreach($vehiclResult as $key=>$value){
if(!is_array($value))
var_dump($value);
else {
foreach($value as $key2=>$value2){
if(!is_array($value2))
var_dump($value2);
else {
foreach($value2 as $key3=>$value3){
var_dump($value3);
}
}
}
}

Iterate through an object's properties and modify the original object

I have this simple issue. In this simple script:
<?php
class MyClass {
public var1 = '1';
public var2 = '';
public var3 = '3';
}
$class = new MyClass;
foreach ($class as $key => $value) {
echo $key . ' => ' . $value . '<br />';
}
?>
The result would be:
var1 => 1
var2 =>
var3 => 3
If I want to iterate through all those properties so I can find out which one is empty, how can I assign a value to that empty property in the object?
foreach ($class as $key => $value) {
if (empty($value)) {
$value = 'something';
}
}
... is not working because I guess that PHP thinks that $value is an actual variable, not a reference.
Try this:
foreach ($class as $key => $value) {
if (empty($value)) {
$value = 'something';
$class->$key = $value;
}
}

Categories