Why my loop return me only "array" - php

I want to return for each vehicule of the API the brand name and the model name
i'm actualy using this loop:
$vehiculecount=count($data);
for($x = 0; $x < $vehiculecount; $x++) {
echo $data[$x];
echo $data[brand][name];
echo "<br>";
}
That actualy return me only :
Array
Array
Array
Array
Array
Array
...
This is what i'm getting in PHP with curl to an API :
{
totalResult: "150",
nbPageList: 2,
createdAt: "2018-05-28T09:23:05+0200",
updatedAt: "2018-05-28T10:55:14+0200",
reference: "5nqts",
reportNumber: 5,
country: "FR",
state: "vehicle.state.parc",
brand: {
reference: "56f50a85cb0f8",
name: "CITROEN"
},
model: {
reference: "57f4d339e38e3",
name: "C3 AIRDREAM BUSINESS"
},
I want to get only 'brand''name' for each vehicle for exemple.
Thx a lot for your help !

First, you should dump, as debugging purpose, the $data object in your loop.
Then, you should see that inside your loop, to acces to an element by its number, you have to use the indexed access like this :
echo $data[$x][brand][name];
Also, to access the brand and name index, you have to use string-key index like this : $data[$x]['brand']['name']

Related

How can I Iterate through PHP multi-dimension array that has label -> value structure

New to PHP (from C#). I have an array ($metaarray), which if I json_encode() to the screen, it has this value:
[
{
"measure":"Walking","record":"steps","latestres":"6870","datet":"2022-08-31"
},{
"measure":"","record":"kilograms","latestres":"117","datet":"2022-09-12"
},{
"measure":"","record":"","latestres":null,"datet":"2022-09-12"
},{
"measure":"Walking","record":"steps","latestres":"6840","datet":"2022-09-12"
},{
"measure":"Bodyweight","record":"kilograms","latestres":"92","datet":"2022-09-12"
},{
"measure":"Benchpress","record":"kilograms","latestres":"90","datet":"2022-09-12"
}
]
Is there an easy way for me to iterate through the metaarray - or to easily reference a record - eg. I would normally do something like:
$latestres = $metaarray[0][2];
...which should be "6870" - however it doesn't return any result when I do that.
Is there a way I can easily reference a particular value (eg. first record, "latestres" or 3rd value) in the above array?
I don't know if this helps you, but $data[2] does not represent third item in an array, unless the array happens to be created linearly (called a list). In PHP, 2 is actually the key to a map (name/value pair). So unless there is actually a key with that index, you can't access it. You can see a demo of what I'm talking about here.
You can get around the feature/limitation by using one of the tricks from this answer: https://stackoverflow.com/a/24825397/231316
function getNthItemFromArray(array $array, int $idx)
{
return $array[array_keys($array)[$idx]];
}
Obviously you'd add some guards.
As everyone notes, you should really start with your data before the encode. However, assuming that for whatever you have a JSON string, you can tell the decoder to give you an associative array instead of an object. Putting that all together you could do something like:
$json = <<<EOT
[
{
"measure":"Walking","record":"steps","latestres":"6870","datet":"2022-08-31"
},{
"measure":"","record":"kilograms","latestres":"117","datet":"2022-09-12"
},{
"measure":"","record":"","latestres":null,"datet":"2022-09-12"
},{
"measure":"Walking","record":"steps","latestres":"6840","datet":"2022-09-12"
},{
"measure":"Bodyweight","record":"kilograms","latestres":"92","datet":"2022-09-12"
},{
"measure":"Benchpress","record":"kilograms","latestres":"90","datet":"2022-09-12"
}
]
EOT;
$decoded = json_decode($json, true);
echo getNthItemFromArray($decoded[0], 2);
function getNthItemFromArray(array $array, int $idx)
{
return $array[array_keys($array)[$idx]];
}
Demo here: https://3v4l.org/POdma

How to get a value of a certain array parameter and put it in another array?

I have the following encoded JSON array
{
"canonList": [{
"deviceId": "Device123",
"deviceModel": "Model123",
"mapList": [{
"alarmStatus": true,
"disabledEndDate": "2020-01-28T15:06:19",
"lastUpdateDate": "2020-01-02T15:06:19",
"ruleDesc": "this is a test description"
}, {
"alarmStatus": true,
"disabledEndDate": "2020-01-28T15:06:19",
"lastUpdateDate": "2020-01-02T15:06:19",
"ruleDesc": "this is a test description 3"
}, {
"alarmStatus": true,
"disabledEndDate": "2020-01-28T15:06:19",
"lastUpdateDate": "2020-01-02T15:06:19",
"ruleDesc": "this is a test description 2"
}]
}, {
"deviceId": "Device1234",
"deviceModel": "Model1234",
"mapList": {
"alarmStatus": true,
"disabledEndDate": "2020-01-28T15:06:19",
"lastUpdateDate": "2020-01-02T15:06:19",
"ruleDesc": "this is a test description 5"
}
}],
"resultCode": 0,
"transactionId": "retrieve_1580400944"
}
I am trying to create an array of just all the values of ruleDesc but I am only getting a null value. The index of the value is dynamic. One thing certain is I need the value inside ruleDesc ...
I've used
$arrayName['canonList']['mapList']['ruleDesc']
but it's only getting the value of the first array.
Any idea?
You need to extract all the mapList entries first, which you can do with array_column. Then you need to check if the maplist value has a ruleDesc key, in which case you add that to your output; otherwise you merge all the ruleDesc from the mapList into the output:
$ruleDesc = array();
foreach (array_column($arrayName['canonList'], 'mapList') as $mList) {
if (isset($mList['ruleDesc'])) {
$ruleDesc[] = $mList['ruleDesc'];
}
else {
$ruleDesc = array_merge($ruleDesc, array_column($mList, 'ruleDesc'));
}
}
print_r($ruleDesc);
Output:
Array
(
[0] => this is a test description
[1] => this is a test description 3
[2] => this is a test description 2
[3] => this is a test description 5
)
Demo on 3v4l.org
As I see you have 2 inner arrays inside your JSON object. The first one is canonList and the second one is mapList so you have to iterate over both of them and add needed values into the result array like this:
$ruleDescs = [];
foreach ($arrayName['cannonList'] as $cannon) {
foreach ($cannon['mapList'] as $map) {
$ruleDescs[] = $map['ruleDesc'];
}
}
print_r($ruleDesc);

Display specific object in array of objects PHP

Supposed i have an array of object of
$test
[
{
my_string: "ciao",
my_number: 10
},
{
my_string: "ciao b",
my_number: 100
},
{
my_string: "ciao c",
my_number: 100
},
{
my_string: "ciao d",
my_number: 100
},
]
How can i display the third object "ciao c" my_string, my_number in the test $array
I tried but it displays all the data i just want only the third object to display
function obj($array){
foreach ($array as $test){
echo $test->my_string. ' ' .$test->my_number. '<br>';
}
}
the desired output should be
ciao c
100
You can access your object like that,
function obj($array){
echo $array[2]->my_string. ' ' .$array[2]->my_number. '<br>';
}
But your definition of object should be proper to achieve this
If you have an array then you can access it by index of element. "Cannot use object of type stdClass as array" this error says that you try to use stdClass as array (in case when you can try access by index).

update value using nested element match in mongo [duplicate]

I have a document in mongodb with 2 level deep nested array of objects that I need to update, something like this:
{
id: 1,
items: [
{
id: 2,
blocks: [
{
id: 3
txt: 'hello'
}
]
}
]
}
If there was only one level deep array I could use positional operator to update objects in it but for second level the only option I've came up is to use positional operator with nested object's index, like this:
db.objects.update({'items.id': 2}, {'$set': {'items.$.blocks.0.txt': 'hi'}})
This approach works but it seems dangerous to me since I'm building a web service and index number should come from client which can send say 100000 as index and this will force mongodb to create an array with 100000 indexes with null value.
Are there any other ways to update such nested objects where I can refer to object's ID instead of it's position or maybe ways to check if supplied index is out of bounds before using it in query?
Here's the big question, do you need to leverage Mongo's "addToSet" and "push" operations? If you really plan to modify just individual items in the array, then you should probably build these arrays as objects.
Here's how I would structure this:
{
id: 1,
items:
{
"2" : { "blocks" : { "3" : { txt : 'hello' } } },
"5" : { "blocks" : { "1" : { txt : 'foo'}, "2" : { txt : 'bar'} } }
}
}
This basically transforms everything in to JSON objects instead of arrays. You lose the ability to use $push and $addToSet but I think this makes everything easier. For example, your query would look like this:
db.objects.update({'items.2': {$exists:true} }, {'$set': {'items.2.blocks.0.txt': 'hi'}})
You'll also notice that I've dumped the "IDs". When you're nesting things like this you can generally replace "ID" with simply using that number as an index. The "ID" concept is now implied.
This feature has been added in 3.6 with expressive updates.
db.objects.update( {id: 1 }, { $set: { 'items.$[itm].blocks.$[blk].txt': "hi", } }, { multi: false, arrayFilters: [ { 'itm.id': 2 }, { 'blk.id': 3} ] } )
The ids which you are using are linear number and it has to come from somewhere like an additional field such 'max_idx' or something similar.
This means one lookup for the id and then update. UUID/ObjectId can be used for ids which will ensure that you can use Distributed CRUD as well.
Building on Gates' answer, I came up with this solution which works with nested object arrays:
db.objects.updateOne({
["items.id"]: 2
}, {
$set: {
"items.$.blocks.$[block].txt": "hi",
},
}, {
arrayFilters: [{
"block.id": 3,
}],
});
MongoDB 3.6 added all positional operator $[] so if you know the id of block that need update, you can do something like:
db.objects.update({'items.blocks.id': id_here}, {'$set': {'items.$[].blocks.$.txt': 'hi'}})
db.col.update({"items.blocks.id": 3},
{ $set: {"items.$[].blocks.$[b].txt": "bonjour"}},
{ arrayFilters: [{"b.id": 3}] }
)
https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/#update-nested-arrays-in-conjunction-with
This is pymongo function for find_one_and_update. I searched a lot to find the pymongo function. Hope this will be useful
find_one_and_update(filter, update, projection=None, sort=None, return_document=ReturnDocument.BEFORE, array_filters=None, hint=None, session=None, **kwargs)
Added reference and pymongo documentation in comments

Create a blank array from a model in cakephp

hi,
I have a working model and I want to be able to just create an array from it but with only the key names and just have them empty.
To illustrate, my model Client comes from the clients table, and for example when I do this:
$this->Client->find( 'first' );
I get the following array (json encoded):
{
Client: {
id: "39",
name: "andrux",
phone: "1234567890",
email: "me#andrux.com",
city_id: "2"
},
City: {
id: "2",
city_name: "andruxville"
}
}
As you can see, I set this model to have a relationship with the City model, so I get both Client and City arrays as a result of my find method.
Now I need to get the same array but without values, and I just can't find an answer for this, I have tried some solutions but none have worked the way I want, for example I tried using array_map function and the schema method of the model but that just gives me the column names of the clients table, which I can set to null if I want but what about the City model?
The end result I want is the following:
{
Client: {
id: "",
name: "",
phone: "",
email: "",
city_id: ""
},
City: {
id: "",
city_name: ""
}
}
Anyone knows how to accomplish this? I rather find a way of doing this the cakephp way - if there is one - but any solution that gets me to my desired result will be greatly appreciated.
Thanks guys!
Well, if its ok, you could create a custom function in your model and pass in the result to it, like:
//can be added to your model
function reset_values($array, $replace_with) {
foreach ($array as $key => $arr) {
if(is_array($arr)) $res[$key] = reset_values($arr,$replace_with);
else $res[$key] = $replace_with;
}
return $res;
}
$resetedArr = reset_values($arr, null); //replace values with null
echo "<pre>"; print_r($resetedArr);

Categories