Convert associative array elements to object only - php

My array
$arr = array(
"name" => "Prakash",
"tall" => "maybe",
"nick_names" => array ("p", "b", "bee", "prak", "new_names" => array("short_name" => "sn", "long_name" => "ln"))
);
I want to be able to create an object from which the values can be accessed via attributes.
e.g.
$obj->name // "PRAKASH"
$obj->nick_names // array("p", "b", "bee", "prak", "new_names" => (object))
How could I get this ?
I seem to able to accomplish exactly what I need through
$obj = json_decode(json_encode($arr));
But obviously that is not the right thing to do.
Thanks.

You can cast it into an stdClass:
$obj = (stdClass) $arr;
Take note that in PHP an array is far superior to an stdClass in any thinkable way.
Better performance
Better traversing abilities
Better readability (IMO)

Related

PHP stdClass & objects foreach

So I have some code looking like this at the moment:
$filter = new \stdClass();
$queryObj = $this->getpost['filter'];
$filters = new \stdClass();
$filters->team = $queryObj['team'];
$filters->skill = $queryObj['skill'];
$filters->division = $queryObj['division'];
$filter->filters = $filters;
$users = $managerStatistics->getManagerDeliveryData($filter);
I fellt the need to do this because in the getManagerDeliveryData(§filter), there is a "foreach $filter->filters"..
Does anyone know how to do this in a better looking way? This looks messy to me but I'm not sure what to do here..
You could rewrite the way you build the data into a more compact format, casting each array definition to an object as needed...
$filter = (object) [
"filters" => (object) [ 'team' => $queryObj['team'],
'skill' => $queryObj['skill'],
'division' => $queryObj['division'] ]
];
If you cast an associative array to an object, it becomes a stdClass object with matching properties. Here's a generic example:
$arr = ['one' => 'foo', 'two' => 'bar', 'three' => 'meh'];
$obj = (object) $arr;
var_dump($obj);
This would give you:
object(stdClass)#2 (3) {
["one"] · string(3) "foo"
["two"] · string(3) "bar"
["three"] · string(3) "meh"
}
In your case, you could do the following, if you're hoping to not have to name your $queryObj keys/values one by one (which is necessary if e.g. the filter list isn't fixed, and therefore can't be hard-coded):
$filters = (object) $queryObj;
Obviously, every key/value pair in the source array then becomes a property/value pair in the object. If there are particular values you want to omit, either unset them or use array_intersect_key() etc. functions to only cast the desired keys. Suppose your $queryObject had a bunch of keys, but you only wanted the ones in your example, you could do this:
$keymap = ['team', 'skill', 'division'];
$filters = (object) array_intersect_key(array_flip($keymap), $queryObject);

Laravel How can I return array of objects

I've got simple array of objects:
"myObject" => [
'key1' => ["property1" => 'value1', "property2" => 'value2'],
'key2' => ["property1" => 'value1', "property2" => 'value2'],
...
],
When I'm returning this via laravel dot syntax:
return [
'listOfObjects' => trans(objects)
]
I've got:
myObject: {
key1: {property1:'value1', property2:'value2'},
key2: {property1:'value1', property2:'value2'},
etc..
}
It's simple.
Now how can I modify my return to get only an array of objects, without numbers:
myObject: {
{property1:'value1', property2:'value2'},
{property1:'value1', property2:'value2'},
etc..
}
Any ideas?
I don't think it is possible to solve in PHP. As it is said in the manual
"...index may be of type string or integer. When index is omitted, an
integer index is automatically generated, starting at 0..."
Also, what you are asking seems to be quite pointless. If you could describe what it is you are trying to accomplish, people might be able to help you better.
The function to use in this case is:
$tryit = trans('objects');
$new = collect($tryit)->flatten(1);
$new->values()->all();
unfortunatelly there is a bug in Laravel 5.6 on this function and it digs two level deep instead of one :/
[edit]
I think I now understand what you want. What you call an Array in PHP is not necessarily an Array in JSON. For JSON your "myObject" is an Object.
For JSON to recognize something as an Array, it can only have numbers as keys.
So change the keys from "key1", "key2", ... into 0, 1, ...
$result = [];
foreach($myObject as $element){
$result[] = $element;
}
return $result;
After that, $result looks like this
$result = [
0 => ["prop1" => "val1", "prop2" => "val2"],
1 => ["prop1" => "val1", "prop2" => "val2"]
]
Or equivalently in the short notation
$result = [
["prop1" => "val1", "prop2" => "val2"],
["prop1" => "val1", "prop2" => "val2"]
]
Now JSON should recognize this as an Array instead of an Object when Laravel converts $result to JSON or you make it yourself: return response()->json($result);
[previous:]
You can not return an object which has values but no keys.
The simplest form of keys are numbers, which is what arrays are using.

PHP Prepend two elements to associative array

I have the following array, I'm trying to append the following ("","--") code
Array
(
[0] => Array
(
[Name] => Antarctica
)
)
Current JSON output
[{"Name":"Antarctica"}]
Desired output
{"":"--","Name":"Antarctica"}]
I have tried using the following:
$queue = array("Name", "Antarctica");
array_unshift($queue, "", "==");
But its not returning correct value.
Thank you
You can prepend by adding the original array to an array containing the values you wish to prepend
$queue = array("Name" => "Antarctica");
$prepend = array("" => "--");
$queue = $prepend + $queue;
You should be aware though that for values with the same key, the prepended value will overwrite the original value.
The translation of PHP Array to JSON generates a dictionary unless the array has only numeric keys, contiguous, starting from 0.
So in this case you can try with
$queue = array( 0 => array( "Name" => "Antarctica" ) );
$queue[0][""] = "--";
print json_encode($queue);
If you want to reverse the order of the elements (which is not really needed, since dictionaries are associative and unordered - any code relying on their being ordered in some specific way is potentially broken), you can use a sort function on $queue[0], or you can build a different array:
$newqueue = array(array("" => "--"));
$newqueue[0] += $queue[0];
which is equivalent to
$newqueue = array(array_merge(array("" => "--"), $queue[0]));
This last approach can be useful if you need to merge large arrays. The first approach is probably best if you need to only fine tune an array. But I haven't ran any performance tests.
Try this:
$queue = array(array("Name" => "Antarctica")); // Makes it multidimensional
array_unshift($queue, array("" => "--"));
Edit
Oops, just noticed OP wanted a Prepend, not an Append. His syntax was right, but we was missing the array("" => "--") in his unshift.
You can try this :
$queue = array("Name" => "Antarctica");
$result = array_merge(array("" => "=="), $queue);
var_dump(array_merge(array(""=>"--"), $arr));

how to convert multidimensional array to object in php?

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.

Best way to refer index which contains in array

In php I'm willing to check the existence of indexes that match with another values in array.
$indexes = array("index", "id", "view");
$fields = array(
"index" => 5,
"id" => 7,
"form" => 10,
"date" => 10,
);
MY ideal result is, in this case, to get "form" and "date". Any idea?
Try
$fields_keys = array_keys($fields);
$fields_unique = array_diff($fields_keys, $indexes);
The result will be an array of all keys in $fields that are not in $indexes.
You can try this.
<?php
$indexes = array("index", "id", "view");
$fields = array(
"index" => 5,
"id" => 7,
"form" => 10,
"date" => 10,
);
$b = array_diff(array_keys($fields), $indexes);
print_r($b);
You can use array_keys function to retrieve keys of a array
Eg:
$array = array(0 => 100, "color" => "red");
print_r(array_keys($array));
Outputs
Array
(
[0] => 0
[1] => color
)
PHP Documentation
Your question is a little unclear but I think this is what you're going for
array_keys(array_diff_key($fields, array_fill_keys($indexes, null)));
#=> Array( 0=>"form", 1=>"date" )
See it work here on tehplayground.com
array_keys(A) returns the keys of array A as a numerically-indexed array.
array_fill_keys(A, value) populates a new array using array A as keys and sets each key to value
array_diff_key(A,B) returns an array of keys from array A that do not exist in array B.
Edit turns on my answer got more complicated as I understood the original question more. There are better answers on this page, but I still think this is an interesting solution.
There is probably a slicker way than this but it will get you started:
foreach(array_keys($fields) as $field) {
if(!in_array($field, $indexes)) {
$missing[] = $field;
}
}
Now you will have an array that holds form and date.

Categories