I have a PHP application with a function that was built to expect information from an API call. However, I'm trying to use this function by passing in information that mimics the API data.
I struggle a bit with arrays and this seems to be an object within an array.
I can access the array that the api provides, so when I use the following code ($triggers is the array the api call returns):
print("<pre>".print_r($triggers,true)."</pre>");
I get the following output:
Array
(
[0] => stdClass Object
(
[triggerid] => 18186
[status] => 0
[value] => 0
)
This is the beginning of the function:
function iterate_triggers($triggers){
$trigger_id_values = array();
foreach($triggers as $trigger) {
//Necessary to show human readable status messages.
$check_status = array(0=>"Up", 1=>"Down", 2=>"Degraded", 3=>"Maintenance");
array_push ($trigger_id_values, [$trigger->triggerid, $trigger->value]);
So if I wanted to pass this function a [triggerid] => 18186 and [value] => 1 how would i do that?
Currently I'm trying:
iterate_triggers(array(0 => array("triggerid" => 18186,"status" => 0,"value" => 1,)));
but this gives me a "Trying to get property of non-object" error. Please be kind to me, I've done my best to research and structure this on my own to no avail.
The easiest way is to cast the assoc array just to an object
In your case this would be
iterate_triggers(array(0 => (object)array("triggerid" => 18186,"status" => 0,"value" => 1,)));
You are currently creating and passing an array that contains an array, while your function expects an array of objects.
You should create your object beforehand, then construct your parameter array, and pass it to your function.
$obj = new \stdClass();
$obj->triggerid = 18186;
$obj->status = 0;
$obj->value = 1;
$arr = array($obj);
iterate_triggers($arr);
This comment on php.net, and the rest of that object documentation, may be useful to you.
By far the easiest and correct way to instantiate an empty generic php object that you can then modify for whatever purpose you choose: <?php $genericObject = new stdClass(); ?>
The error message you are seeing with your own code is caused by $trigger->triggerid inside the function, when $trigger is an array instead of an object as the function expects. Object properties are accessed using $someObject->propertyName notation, while array elements are accessed using $someArray['keyName']
Related
This question already has answers here:
Cannot use object of type stdClass as array?
(17 answers)
Closed 1 year ago.
I'm trying to loop over some data in one of my Laravel's job files. I'm successfully able to get my data, and can see it when I log it to a file, but for some strange reason when I try to iterate over my data with a foreach loop, I'm getting this error:
Cannot use object of type stdClass as array
public function handle()
{
$filters = json_decode($this->report->discovery_filters);
Log::debug($filters); // gives me my data which I'll attach
foreach ($filters as $key => $findable) {
Log::debug($findable['query']['table']); // errors
die;
}
}
My data:
[2021-03-10 14:11:57] local.DEBUG: array (
0 =>
(object) array(
'name' => 'Sessions',
'componentID' => 2435,
'query' =>
(object) array(
'table' => 'data_google_analytics'
// etc... too much data to attach the rest, but 'query' and then 'table' clearly exists
What am I missing?
The error’s telling you what the problem is: you’re trying to use an object as an array.
Instead, force the JSON to be decoded to arrays rather than arrays and objects by specifying true as the second parameter in json_decode:
$filters = json_decode($this->report->discovery_filters, true);
This will force json_decode to turn objects into associative arrays instead.
I have dataset like the following, one of my table column let say prices column store prices in json format, example given below.
<?php
$dataSet[] = array(
"product_id" => 1,
"prices" => '{"1":"29990", "2": "10000"}'
);
foreach ($dataSet as $dataRow)
{
$pricesStdClassObject = json_decode($dataRow['prices']);
// Convert stdClass Object into array
$pricesArray = (array) $pricesStdClassObject;
print_r($pricesArray);
}
?>
The output of print_r($pricesArray) is the following
Array ( [1] => 29990 [2] => 10000 )
Then why print_r($pricesArray[1]) give me error
A PHP Error was encountered
Severity: Notice
Message: Undefined offset: 1
But why?
And finally i found the solution:
According to the documentation here and from the forum here I found a ‘assoc’ parameter of json_decoded method that used with this method and by default its value is FLASE, json_decoded return stdClass objects if you want the returned objects converted into associative arrays then you have to make the ‘assoc’ parameter value to TRUE like the following.
$pricesStdClassObject = json_decode($dataRow['prices'], TRUE);
So the above example code will become like this
<?php
$dataSet[] = array(
"prices" => '{"1":"29990", "2": "10000"}'
);
foreach ($dataSet as $dataRow)
{
$pricesArray = json_decode($dataRow['prices'], TRUE);
// returned objects will be converted into associative arrays.
print_r($pricesArray);
}
?>
And then you can access the indexed value with no error message :)
print_r($pricesArray[1]); output: 29990
Array type casting with json decoded StdClass Objects is not working properly, you can skip the following piece of code if you are using the ‘assoc’ parameter.
// Convert stdClass Object into array
$pricesArray = (array) $pricesStdClassObject;
I have an empty array in a remote file but intend to momentarily add and alter objects in it. However, after adding an initial first set of objects, the array does not accept any more values. My error log reports unexpected 'Object' (T_STRING), expecting ')' meaning it regards the keyword "Object" as a string imputed by me so I guess the problem originates from my array structure. Here is the code I used in adding the objects
include 'all_users.php';
$francis_udeh = new Admin("francis_udeh");
$all_users['francis_udeh'] = $francis_udeh;
$victor_nwafor = new Member("victor_nwafor");
$all_users['victor_nwafor'] = $victor_nwafor;
$print_arr = print_r($all_users, TRUE);
$updated_arr = "<?php \n \$all_users = $print_arr; \n?>";
file_put_contents('all_users.php', $updated_arr);
returns the following in the remote file
<?php
$all_users = Array
(
[francis_udeh] => Admin Object
(
[name] => francis udeh
[pagename] => francis.udeh
[can_comment] => 1
[can_view_announcements] => 1
[profile_pic] => /blog/accounts/assets/user.png
[can_delete_comment] => 1
)
[victor_nwafor] => Member Object
(
[name] => victor nwafor
[pagename] => victor.nwafor
[can_comment] => 1
[can_view_announcements] => 1
[profile_pic] => /blog/accounts/assets/user.png
)
);
?>
(which, by the way, is what I want). However, when I try
include 'all_users.php';
$raheem_sadiq = new Member("raheem_sadiq");
$all_users['raheem_sadiq'] = $raheem_sadiq;
$print_arr = print_r($all_users, TRUE);
$updated_arr = "<?php \n \$all_users = $print_arr; \n?>";
file_put_contents('all_users.php', $updated_arr);
it returns the error I posted earlier resulting in the array not changing. What am I doing wrong?
You include all_users.php at the beginning of code, but after first file_put_contents() it's a not correct php code in this file.
As #Indra already mentioned: the output given by print_r() is human readable, but not valid php code. If you don't have the possibilty to pass the data via a data storage (like mysql), it might be a workaround to put it to the file with serialize(). Alternatively, you could also use json (as your objects seem to be data access objects of some same kind) and then instantiate the objects remotely.
Hope this helps,
Greetings
I have a array which I am printing using print_r.
<?php
print_r ($this)
?>
I get following result in my browser.
PackingListForm Object
(
[objShipment:protected] => Shipment Object
(
[objCustomFieldArray] =>
[intShipmentId:protected] => 38
[strShipmentNumber:protected] => 1035
[intTransactionId:protected] => 97
[intFromCompanyId:protected] => 1
[intFromContactId:protected] => 1
[intFromAddressId:protected] => 1
[intToCompanyId:protected] => 2
[intToContactId:protected] => 3
[intToAddressId:protected] => 2
[intCourierId:protected] => 1
[strTrackingNumber:protected] =>
[dttShipDate:protected] => QDateTime Object
)
)
Now I want to print / echo intTransactionId.
I have used following variable to echo the result, but I am getting undefined variable.
<?php
$noted = $this->objShipment->intTransactionId;
print_r ($noted);
?>
I am getting following php exception error in my browser.
Undefined GET property or variable in 'Shipment' class: intTransactionId
Line 33: $noted = $this->objShipment->intTransactionId;
My question is how can I echo / print value of intTransactionId?
intTransactionId is a protected property which means that you can't access it outside of the class itself (or parennt class or child class).
The exception, I think, is thrown in a __get magic method defined in Shipment (or one of its parent classes). This method is called when trying to access an unset property (or non-accesible property).
Please check this behaviour.
First try to convert it into array and then it will be much easier :),
$newArray = (array)$this;
print_r($newArray);//to see what can you get from there
// get_object_vars
$newArray = get_object_vars($object);
The object is from class PackingListForm, have look on that class if you have access and see if there is any get() function.
i have a multidimensional array:
$image_path = array('sm'=>$sm,'lg'=>$lg,'secondary'=>$sec_image);
witch looks like this:
[_media_path:protected] => Array
(
[main_thumb] => http://example.com/e4150.jpg
[main_large] => http://example.com/e4150.jpg
[secondary] => Array
(
[0] => http://example.com/e4150.jpg
[1] => http://example.com/e4150.jpg
[2] => http://example.com/e9243.jpg
[3] => http://example.com/e9244.jpg
)
)
and i would like to convert it into an object and retain the key names.
Any ideas?
Thanks
edit: $obj = (object)$image_path; doesn't seem to work. i need a different way of looping through the array and creating a object
A quick way to do this is:
$obj = json_decode(json_encode($array));
Explanation
json_encode($array) will convert the entire multi-dimensional array to a JSON string. (php.net/json_encode)
json_decode($string) will convert the JSON string to a stdClass object. If you pass in TRUE as a second argument to json_decode, you'll get an associative array back. (php.net/json_decode)
I don't think the performance here vs recursively going through the array and converting everything is very noticeable, although I'd like to see some benchmarks of this. It works, and it's not going to go away.
The best way would be to manage your data structure as an object from the start if you have the ability:
$a = (object) array( ... ); $a->prop = $value; //and so on
But the quickest way would be the approach supplied by #CharlieS, using json_decode(json_encode($a)).
You could also run the array through a recursive function to accomplish the same. I have not benchmarked this against the json approach but:
function convert_array_to_obj_recursive($a) {
if (is_array($a) ) {
foreach($a as $k => $v) {
if (is_integer($k)) {
// only need this if you want to keep the array indexes separate
// from the object notation: eg. $o->{1}
$a['index'][$k] = convert_array_to_obj_recursive($v);
}
else {
$a[$k] = convert_array_to_obj_recursive($v);
}
}
return (object) $a;
}
// else maintain the type of $a
return $a;
}
Hope that helps.
EDIT: json_encode + json_decode will create an object as desired. But, if the array was numerical or mixed indexes (eg. array('a', 'b', 'foo'=>'bar') ), you will not be able to reference the numerical indexes with object notation (eg. $o->1 or $o[1]). the above function places all the numerical indexes into the 'index' property, which is itself a numerical array. so, you would then be able to do $o->index[1]. This keeps the distinction of a converted array from a created object and leaves the option to merge objects that may have numerical properties.