How to loop through array of objects in PHP - php

I'm very new to PHP and I need your help!
I need to write backend for my app that receives json post and write data to json file. And I'm stuck with looping through array.
$postData = file_get_contents("php://input");
$request = json_decode($postData);
var_damp($request)
shows array:
array(2) {
[0]=>
object(stdClass)#1 (8) {
["name"]=>
string(11) "Alex Jordan"
["email"]=>
string(14) "alex#gmail.com"
["phone"]=>
int(123456789)
["street"]=>
string(12) "street, str."
["city"]=>
string(7) "Chicago"
["state"]=>
string(7) "Chicago"
["zip"]=>
string(5) "07202"
["$$hashKey"]=>
string(8) "object:3"
}
[1]=>
object(stdClass)#2 (8) {
["name"]=>
string(15) "Michael Jonhson"
["email"]=>
string(17) "michael#gmail.com"
["phone"]=>
float(11987654321)
["street"]=>
string(12) "street, str."
["city"]=>
string(11) "Los Angeles"
["state"]=>
string(10) "California"
["zip"]=>
string(5) "27222"
["$$hashKey"]=>
string(8) "object:4"
}
}
I'm trying to loop through the objects and getting error
Object of class stdClass could not be converted to string
Here is how I'm trying to do it:
foreach($request as $i => $i_value) {
echo $i_value;
}

$i_value is the object. Because it's an object you cannot just echo it (unlike in JavaScript where you can cast any object to string).
You can echo specific properties of the object:
foreach($request as $i => $i_value) {
echo $i_value->name;
}
Of course you could also use var_dump again to dump each object. print_r should work too.
Objects can only be casted to string like you do if they implement the __toString() magic method, but the objects created by json_decode are just simple StdClass objects that do not implement this. It's probably not your intention to do this at all, but if you're curious, you may have a look at json_decode to custom class to see how you may use a custom class instead of StdClass.

I had the same problem recently. I used a for loop to loop through the array which gave me an error of undefined offset. Using isset() solved the error of undefined offset. I know its too late to answer this question but here it is for someone who might be looking for it in future
$postData = file_get_contents("php://input");
$request = json_decode($postData);
// or you can do $postData = json_decode(file_get_contents("php://input"));
$arrayOfUsers = $request->data; // I used a key of data while sending the array via fetch API
for($x = 0; $x < count($arrayOfUsers); $x++)
{
if(isset($arrayOfUsers[$x]))
{
$name = $arrayOfUsers[$x]->name;
$email = $arrayOfUsers[$x]->email;
$phone = $arrayOfUsers[$x]->phone;
$street = $arrayOfUSers[$x]->street;
// .... and so on
// then you can do whatever you want with the data
} else {
echo "No Data Found";
}
}

You can also use array_map(?callable $callback, array $array, array ...$arrays): array
to get required properties of each object;
or even alter its data.
This code covers both cases (sandbox_url):
<?php
$arr_of_objects[] = (object)['field_name' => 'test2', 'id' => 2];
$arr_of_objects[] = (object)['field_name' => 'test', 'id' => 1];
$array_of_names = array_map(function ($el) {
return $el->field_name;
}, $arr_of_objects);
echo 'get field_name from array of objects' . "\n";
var_dump($array_of_names);
$replace_data_with = [
1 => ['field_name' => 'replaced_name_1', 'id' => 777],
2 => ['field_name' => 'replaced_name_2', 'id' => 999]
];
$changed_values = array_map(function ($el) use ($replace_data_with) {
$el->field_name = $replace_data_with[$el->id]['field_name'];
$el->id = $replace_data_with[$el->id]['id'];
return $el;
}, $arr_of_objects);
echo 'alter data of each object' . "\n";
var_dump($changed_values);
Base array of Objects:
array(2) {
[0]=>
object(stdClass)#1 (2) {
["field_name"]=>
string(5) "test2"
["id"]=>
int(2)
}
[1]=>
object(stdClass)#2 (2) {
["field_name"]=>
string(4) "test"
["id"]=>
int(1)
}
}
Output:
get field_name from array of objects
array(2) {
[0]=>
string(5) "test2"
[1]=>
string(4) "test"
}
alter data of each object
array(2) {
[0]=>
object(stdClass)#1 (2) {
["field_name"]=>
string(15) "replaced_name_2"
["id"]=>
int(999)
}
[1]=>
object(stdClass)#2 (2) {
["field_name"]=>
string(15) "replaced_name_1"
["id"]=>
int(777)
}
}

Related

Add array to array without key IDs? - PHP

I have a big array which looks like this:
array(2) {
["Final Fantasy VII"]=>
array(5) {
["rows"]=>
array(2) {
[0]=>
array(6) {
["price"]=>
string(5) "11.69"
["price_old"]=>
string(4) "4.66"
["currency"]=>
string(4) "euro"
["portal"]=>
string(0) ""
["link"]=>
string(77) "https://de.gamesplanet.com/game/final-fantasy-vii-download--1001-1?ref=gmkeys"
["shop"]=>
string(4) "9507"
}
[1]=>
array(6) {
["price"]=>
string(5) "14.99"
["price_old"]=>
...
}
}
}
["Battlefield 1"]=>
array(3) {
["rows"]=>
array(2) {
[0]=>
array(6) {
["price"]=>
...
}
[1]=>
array(6) {
["price"]=>
...
}
}
}
}
And I want to get only certain parts of this array where the name is matching my searched title. So, I use this code for that:
function createACFRepeater($title){
$repeater = array();
if(searchForGameXML($title)){
$count = count($GLOBALS["productsXML"][$title]['rows']);
for($i = 0; $i < $count; $i++){
array_push($repeater, $GLOBALS["productsXML"][$title]['rows'][$i]);
}
return $repeater;
}else{
return $repeater;
}
}
My problem now is that the the $repeater array looks like this:
array(2) {
[0]=>
array(6) {
["price"]=>
string(5) "19.98"
["price_old"]=>
...
}
[1]=>
array(6) {
["price"]=>
string(4) "7.99"
["price_old"]=>
...
}
}
There is a numeric key which is pointing to the array [0] => .... But what I want is simply an array in a array without any associative relations...
How can I create an array which looks like this:?
array(2) {
array(6) {
["price"]=>
string(5) "19.98"
["price_old"]=>
...
}
array(6) {
["price"]=>
string(4) "7.99"
["price_old"]=>
...
}
}
Greetings and Thank You!
According to the array definition it is impossible. Any array item must have key and value, documentation for array starts from:
An array in PHP is actually an ordered map. A map is a type that associates values to keys
You will always have numeric keys. As #lubart already said: it's impossible to have an array without keys. Btw., all of the the follwing arrays are completely equal:
$array1 = array([0] => array([0] => 'hi', [1] => array([0] => '23.5')));
$array2 = array(array('hi', array('23.5')));
$array3 = [['hi', ['23.5']]];
$array4 = [ [0] => [ [0] => 'hi', [1] => [ [0] => '23.5' ] ] ];

Updating nested arrays with Laravel

First sorry, i am only developing in php for a month and i do not know how to update this with laravel
I would like to update multiple photos.
Photos have a title description, etc.
My problem is i have no clue how to do it.
I tried the following
public function update(Request $request, Photo $photo)
{
// loop through array of id's
foreach ($request->photo_id as $id)
{
// find
$photos = $photo->find($id);
// loop throug input fields
foreach ($request->except('_token', 'tags', 'photo_id') as $key => $value)
{
$photos->$key = $value;
$photos->save();
}
}
die();
}
I get the following error
preg_replace(): Parameter mismatch, pattern is a string while replacement is an array
So i figured out the problem is with the value
And the results are like this
Key variable
string(5) "title"
string(10) "country_id"
string(7) "city_id"
string(11) "category_id"
string(9) "cruise_id"
string(12) "itinerary_id"
string(4) "desc"
string(6) "people"
string(5) "title"
string(10) "country_id"
string(7) "city_id"
string(11) "category_id"
string(9) "cruise_id"
string(12) "itinerary_id"
string(4) "desc"
string(6) "people"
Value variable results
array(2) {
[0]=>
string(9) "title one"
[1]=>
string(9) "title two"
}
array(2) {
[0]=>
string(1) "1"
[1]=>
string(1) "1"
}
array(2) {
[0]=>
string(1) "1"
[1]=>
string(1) "1"
}
array(2) {
[0]=>
string(0) ""
[1]=>
string(0) ""
}
array(2) {
[0]=>
string(1) "1"
[1]=>
string(0) ""
}
array(2) {
[0]=>
string(1) "1"
[1]=>
string(0) ""
}
I tried several other attempts but nothing works
Could please someone help me out with this?
Without knowing more about what is passing you the request object, I can't really go into specifics but you probably want to get your request object to look something like this:
'photos' => [
{
'id' => 1,
'title' => 'title one',
// more properties ....
},
{
'id' => 2,
'title' => 'title two',
// more properties ....
},
]
Then try something like this:
public function update(Request $request)
{
// Loop through the request photo id's
$request->photos->each(function($photo) use ($request) {
// Return the photo object you want to update
$photo = Photo::find($photo->id);
// Get the things you want from the request and update the object
$photo->title= $request[$photo_id]->title;
// Save the object
$photo->save();
})
}
You also may want to try out the dd(); function instead of die();. It makes debugging a lot easier.
I think, Photo Model missed the fillable array.
protected $fillable = ['var1', 'var2', ...];

PHP ARRAY get index of item for certain value

I have these 2 arrays $fonts['google'] and $data['value'] with the following content:
var_dump ($fonts['google']) outputs
array(4) {
[0]=> array(3) { ["family"]=> string(7) "ABeeZee" ["variants"]=> array(2) { [0]=> string(7) "regular" [1]=> string(6) "italic" } ["subsets"]=> array(1) { [0]=> string(5) "latin" } }
[1]=> array(3) { ["family"]=> string(4) "Abel" ["variants"]=> array(1) { [0]=> string(7) "regular" } ["subsets"]=> array(1) { [0]=> string(5) "latin" } }
[2]=> array(3) { ["family"]=> string(13) "Abril Fatface" ["variants"]=> array(1) { [0]=> string(7) "regular" } ["subsets"]=> array(2) { [0]=> string(5) "latin" [1]=> string(9) "latin-ext" } }
[3]=> array(3) { ["family"]=> string(8) "Aclonica" ["variants"]=> array(1) { [0]=> string(7) "regular" } ["subsets"]=> array(1) { [0]=> string(5) "latin" } }
}
var_dump ($data['value']) outputs
array(4) {
["size"]=> int(17)
["family"]=> string(3) "Exo"
["style"]=> string(3) "200"
["subsets"]=> string(5) "latin"
}
Now I get the $data['value']['family'] = 'Abel' from my database.
Questions:
How can I get the ['variants'] for the given $data['value']['family'] value?
How can I get the index in $fonts['google'] for the sub-array where the $data['value']['family'] value is?
PHP supports Associative Arrays which let you use a (string) key rather than a numeric index for each element. These arrays are akin to javascript objects, Objective-C dictionaries, java HashMaps, etc.
That makes scenarios like this easy. Do you have control over building the original data array? If you can refactor your storage, set up the arrays like this:
$fonts['google'] = [
["ABeeZee"] => [
["variants"]=>["regular", "italic"],
["subsets"]=>["latin"]
],
["Abel"] => [
["variants"]=>["regular"],
["subsets"]=>["latin"]
],
["Abril Fatface"] => [
["variants"]=>["regular"],
["subsets"]=>["latin", "latin-ext"]
],
["Aclonica"] => [
["variants"]=>["regular"],
["subsets"]=>["latin"]
]
]
extra credit: if you have the original data as in the post, you could convert it:
$newArray = array(); // or just [] in PHP >= 5.3 I believe
foreach($fonts['google'] as $index=>$fontArray) {
$newArray[$fontArray['family']] = $fontArray;
// this leaves a redundant copy of the family name in the subarray
unset $newArray[$fontArray['family']]['family']; // if you want to remove the extra copy
}
Then it becomes trivial. Given a font family name, you just access $fonts['google'][$fontFamilyName] (or $newArray[$fontFamilyName]) using the family name as the array index.

How to filter array to get only the object and not array in PHP

I'm not even sure what to search for for this question. What I really want is I have an array of objects like this
array(3) {
[0]=>
object(stdClass)#423 (4) {
["name"]=>
string(3) "Blah"
["full_name"]=>
string(10) "/Blah"
["id"]=>
string(32) "BlahBlah"
["parent_id"]=>
string(32) "BlahBlah"
}
[1]=>
object(stdClass)#422 (4) {
["name"]=>
string(8) "Blah1"
["full_name"]=>
string(9) "Blah2"
["id"]=>
string(32) "BlahBlah2"
["parent_id"]=>
NULL
}
[2]=>
object(stdClass)#421 (4) {
["name"]=>
string(4) "Blah3"
["full_name"]=>
string(11) "Blah3"
["id"]=>
string(32) "BlahBlah3"
["parent_id"]=>
string(32) "BlahBlahBlah3"
}
}
I want to filter to just the object that I want so what I did was
$found_label = array_filter($labels, function($obj) use($label) {
return $obj->name === $label;
});
But then the results I got is this
array(1) {
[1]=>
object(stdClass)#422 (4) {
["name"]=>
string(8) "Blah1"
["full_name"]=>
string(9) "Blah1"
["id"]=>
string(32) "BlahBlah2"
["parent_id"]=>
NULL
}
}
But what I really want is just this
object(stdClass)#422 (4) {
["name"]=>
string(8) "Blah1"
["full_name"]=>
string(9) "Blah1"
["id"]=>
string(32) "BlahBlah2"
["parent_id"]=>
NULL
}
Then I have to do this to just get the actual object
$theKey = key($found_label);
return $found_label[$theKey];
I thought they should be a better way of doing this, also I'm new to PHP.
You can't do that with array_filter, there is no way to stop it and return only the first result. If you can't use the key to extract the result you want from the array returned from array_filter, you should use a loop. Something like this:
$label = "wantedLabel";
foreach ($labels as $l) {
if( $l->name === $label ) {
print_r ($l);
break;
}
}
This:
<?php
$labels = array(
"0" => (object) array('name' => "name1", "title" => "title1"),
"1" => (object) array('name' => "name2", "title" => "title2")
);
$label = "name1";
$found_label = array_filter($labels, function($obj) use($label) {
return $obj->name === $label;
});
print_r($found_label[0]);
Produces:
stdClass Object ( [name] => name1 [title] => title1 )

get the specified outpot using php 2d array

I have got a 2d array called $myarray, and when I using var_dump($myarray), it gives me the following:
array(4) { [0]=> array(2) { [0]=> string(3) "EUR" [1]=> string(9) "43,543.23" } [1]=> array(2) { [0]=> string(3) "USD" [1]=> string(9) "13,432.34" } [2]=> array(2) { [0]=> string(3) "GBP" [1]=> string(8) "3,432.21" } [3]=> array(2) { [0]=> string(3) "CAD" [1]=> string(8) "2,321.34" } }
But I want the output to be the follwing format:
Totals
GBP 3,432.21
USD 13,432.34
EUR 43,543.23
CAD 2,321.34
I assume that I need to sort the array to be:
GBP 3,432.21
USD 13,432.34
EUR 43,543.23
CAD 2,321.34
and add "Totals", "" into the array, I might be wrong, soanybody could help me with that, any help will be greatly appreciated! I want it to be done in a programmatic way! how to sort the array $myarray to the expected output?
You're almost right.
Don't add the 'Totals' into the array. It is not data, mere decoration. For the rest, I wouldn't 'dump' the array, but e.g. for a string from it. As a rule, don't change your data especially for output formatting reasons, you'll find yourself removing the 'Totals' entry in the next function processing the data...:
Also, you want to control the iteration order; therefore you can iterate over the desired keys instead of over the array itself:
$output="Totals:\n";
foreach( $currency in array("GBP","USD","EUR","CAD") ) {
$entry=$data[$currency];
$output.=$currency." ".$entry[1]."\n";
}
dump($output);
EDIT - added the bit about ordering
Firstly, do not add anything non-data related to your array. You the string "Totals" should not be included in your array. If you just want the output, I suggest a better way to solve your problem :
<?php
class MyMoney {
var $type;
var $value;
public function __toString() {
return $type." ".$value."\n";
}
}
$output="Totals:\n";
// $data is an array of MyMoney objects
foreach( $entry in $data ) {
$output.= (string) $entry;
}
dump($output);
I hope this helps.
I'm not sure if this is what you're describing but perhaps it can be of use in your situation:
$myArray = array(
"title" => "Totals",
"data" => array(
"GBP" => "3,432.21",
"USD" => "13,432.34",
"EUR" => "43,543.23",
"CAD" => "2,321.34"
)
);
var_dump($myArray);
Output:
array(2) {
["title"]=>
string(6) "Totals"
["data"]=>
array(4) {
["GBP"]=>
string(8) "3,432.21"
["USD"]=>
string(9) "13,432.34"
["EUR"]=>
string(9) "43,543.23"
["CAD"]=>
string(8) "2,321.34"
}
}
<?php
$output = "Totals<br>";
foreach ($myarray as $value)
{
$output .= $value[0].' '.$value[1].'<br>';
}
echo $output;
?>

Categories