Reputation: 32908
How can I convert an array like this to an object?
[128] => Array
(
[status] => "Figure A.
Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution."
)
[129] => Array
(
[status] => "The other day at work, I had some spare time"
)
Upvotes: 506
Views: 1170499
Reputation: 13056
It's way too simple, This will create an object for recursive arrays as well:
$object = json_decode(json_encode((object) $yourArray), FALSE);
Upvotes: 55
Reputation: 2103
If you need to cast an array to a specific class (as in my case I need the object to be of type Google_Service_AndroidPublisher_Resource_Inappproducts for my mock), you can str_replace the class name from stdClass to the intended class like this:
function castArrayToClass(array $array, string $className)
{
//first cast the array to stdClass
$subject = serialize((object)$array);
//then change the class name
$converted = str_replace(
'O:8:"stdClass"',
'O:'.strlen($className).':"'.$className.'"',
$subject
);
unset($subject);
return unserialize($converted);
}
Upvotes: 0
Reputation: 548
I also had this issue, but I noticed that json_decode converts JSON array to object.
So, I came about my solution by using json_encode($PHPArray) which returns A JSON string of object, then I decoded the string with Json_decode($string) and it would return a perfectly structured object. Shorthand
$object = json_decode(json_encode($array));
Or
$jsonString = json_encode($array);
$object = json_decode($jsonString);
Upvotes: 31
Reputation: 413
You can use the (object) function to convert your array into an object.
$arr= [128=> ['status'=>
'Figure A. Facebook \'s horizontal scrollbars showing up on a 1024x768 screen resolution.'],
129=>['status'=>'The other day at work, I had some spare time']];
$ArrToObject=(object)$arr;
var_dump($ArrToObject);
The result will be an object that contains arrays:
object(stdClass)#1048 (2) { [128]=> array(1) {
["status"]=> string(87) "Figure A. Facebook 's horizontal scrollbars showing up on a 1024x768 screen resolution." }
[129]=> array(1) { ["status"]=> string(44) "The other day at work, I had some spare time" } }
Upvotes: 26
Reputation: 404
You can use Reflection:
<?php
$array = ['name'=>'maria','age'=>33];
class Person {
public $name;
public $age;
public function __construct(string $name, string $age){
$this->name = $name;
$this->age = $age;
}
}
function arrayToObject(array $array, string $class_name){
$r = new ReflectionClass($class_name);
$object = $r->newInstanceWithoutConstructor();
$list = $r->getProperties();
foreach($list as $prop){
$prop->setAccessible(true);
if(isset($array[$prop->name]))
$prop->setValue($object, $array[$prop->name]);
}
return $object;
}
$pessoa1 = arrayToObject($array, 'Person');
var_dump($pessoa1);
Upvotes: 3
Reputation: 4254
Multidimensional arrays into an object. this code is used for conversion of Bing search API try and catch method.
try {
// Perform the Web request and get the JSON response
$context = stream_context_create($options);
$results = file_get_contents($url . "?cc=" . $country . "&category=" . $type, false, $context);
$results = json_decode($results);
return response()->json($results);
} catch (\Exception $e) {
$results = array('value' => array(
(object) array(
"name" => "Unable to Retrive News",
"url" => "http://www.sample.com/",
"image" => (object) array("thumbnail" => (object) array("contentUrl" => "")),
"publishedAt" => "",
"description" => "")
)
);
$results = (object) $results;
return response()->json($results);
}
Upvotes: 3
Reputation: 1691
Little complicated but easy to extend technique:
Suppose you have an array
$a = [
'name' => 'ankit',
'age' => '33',
'dob' => '1984-04-12'
];
Suppose you have have a Person class which may have more or less attributes from this array. for example
class Person
{
private $name;
private $dob;
private $age;
private $company;
private $city;
}
If you still wanna change your array to the person object. You can use ArrayIterator Class.
$arrayIterator = new \ArrayIterator($a); // Pass your array in the argument.
Now you have iterator object.
Create a class extending FilterIterator Class; where you have to define the abstract method accept. Follow the example
class PersonIterator extends \FilterIterator
{
public function accept()
{
return property_exists('Person', parent::current());
}
}
The above impelmentation will bind the property only if it exists in the class.
Add one more method in the class PersonIterator
public function getObject(Person $object)
{
foreach ($this as $key => $value)
{
$object->{'set' . underscoreToCamelCase($key)}($value);
}
return $object;
}
Make sure you have mutators defined in your class. Now you are ready to call these function where you want to create object.
$arrayiterator = new \ArrayIterator($a);
$personIterator = new \PersonIterator($arrayiterator);
$personIterator->getObject(); // this will return your Person Object.
Upvotes: 12
Reputation: 939
The one I use (it is a class member):
const MAX_LEVEL = 5; // change it as needed
public function arrayToObject($a, $level=0)
{
if(!is_array($a)) {
throw new InvalidArgumentException(sprintf('Type %s cannot be cast, array expected', gettype($a)));
}
if($level > self::MAX_LEVEL) {
throw new OverflowException(sprintf('%s stack overflow: %d exceeds max recursion level', __METHOD__, $level));
}
$o = new stdClass();
foreach($a as $key => $value) {
if(is_array($value)) { // convert value recursively
$value = $this->arrayToObject($value, $level+1);
}
$o->{$key} = $value;
}
return $o;
}
Upvotes: 8
Reputation: 137
This requires PHP7 because I chose to use a lambda function to lock away the 'innerfunc' within the main function. The lambda function is called recursively, hence the need for: "use ( &$innerfunc )". You could do it in PHP5 but could not hide the innerfunc.
function convertArray2Object($defs) {
$innerfunc = function ($a) use ( &$innerfunc ) {
return (is_array($a)) ? (object) array_map($innerfunc, $a) : $a;
};
return (object) array_map($innerfunc, $defs);
}
Upvotes: 8
Reputation: 15989
The easy way would be
$object = (object)$array;
But that's not what you want. If you want objects you want to achieve something, but that's missing in this question. Using objects just for the reason of using objects makes no sense.
Upvotes: 168
Reputation: 1789
one liner
$object= json_decode(json_encode($result_array, JSON_FORCE_OBJECT));
Upvotes: 7
Reputation: 212
use this function that i've made:
function buildObject($class,$data){
$object = new $class;
foreach($data as $key=>$value){
if(property_exists($class,$key)){
$object->{'set'.ucfirst($key)}($value);
}
}
return $object;
}
Usage:
$myObject = buildObject('MyClassName',$myArray);
Upvotes: 6
Reputation: 3444
Here are three ways:
Fake a real object:
class convert
{
public $varible;
public function __construct($array)
{
$this = $array;
}
public static function toObject($array)
{
$array = new convert($array);
return $array;
}
}
Convert the array into an object by casting it to an object:
$array = array(
// ...
);
$object = (object) $array;
Manually convert the array into an object:
$object = object;
foreach ($arr as $key => $value) {
$object->{$key} = $value;
}
Upvotes: 106
Reputation: 28742
I use the following to parse Yaml files associative arrays into an object state.
This checks all supplied arrays if there are objects hiding there, and turns them also in objects.
/**
* Makes a config object from an array, making the first level keys properties a new object.
* Property values are converted to camelCase and are not set if one already exists.
* @param array $configArray Config array.
* @param boolean $strict To return an empty object if $configArray is not an array
* @return stdObject The config object
*/
public function makeConfigFromArray($configArray = [],$strict = true)
{
$object = new stdClass();
if (!is_array($configArray)) {
if(!$strict && !is_null($configArray)) {
return $configArray;
}
return $object;
}
foreach ($configArray as $name => $value) {
$_name = camel_case($name);
if(is_array($value)) {
$makeobject = true;
foreach($value as $key => $val) {
if(is_numeric(substr($key,0,1))) {
$makeobject = false;
}
if(is_array($val)) {
$value[$key] = $this->makeConfigFromArray($val,false);
}
}
if($makeobject) {
$object->{$name} = $object->{$_name} = $this->makeConfigFromArray($value,false);
}
else {
$object->{$name} = $object->{$_name} = $value;
}
}
else {
$object->{$name} = $object->{$_name} = $value;
}
}
return $object;
}
This turns a yaml configured as
fields:
abc:
type: formfield
something:
- a
- b
- c
- d:
foo:
bar
to an array consisting of:
array:1 [
"fields" => array:1 [
"abc" => array:2 [
"type" => "formfield"
"something" => array:4 [
0 => "a"
1 => "b"
2 => "c"
3 => array:1 [
"d" => array:1 [
"foo" => "bar"
]
]
]
]
]
]
to an object of:
{#325
+"fields": {#326
+"abc": {#324
+"type": "formfield"
+"something": array:4 [
0 => "a"
1 => "b"
2 => "c"
3 => {#328
+"d": {#327
+"foo": "bar"
}
}
]
}
}
}
Upvotes: 0
Reputation: 20010
In the simplest case, it's probably sufficient to "cast" the array as an object:
$object = (object) $array;
Another option would be to instantiate a standard class as a variable, and loop through your array while re-assigning the values:
$object = new stdClass();
foreach ($array as $key => $value)
{
$object->$key = $value;
}
As Edson Medina pointed out, a really clean solution is to use the built-in json_
functions:
$object = json_decode(json_encode($array), FALSE);
This also (recursively) converts all of your sub arrays into objects, which you may or may not want. Unfortunately it has a 2-3x performance hit over the looping approach.
Warning! (thanks to Ultra for the comment):
json_decode on different enviroments converts UTF-8 data in different ways. I end up getting on of values '240.00' locally and '240' on production - massive dissaster. Morover if conversion fails string get's returned as NULL
Upvotes: 828
Reputation: 57
Best Method in the WORLD :)
function arrayToObject($conArray)
{
if(is_array($conArray)){
/*
* Return array converted to object
* Using __FUNCTION__ (Magic constant)
* for recursive call
*/
return (object) array_map(__FUNCTION__, $conArray);
}else{
// Return object
return $conArray;
}
}
if you use different methods you will have problems. This is the best method. You have ever seen.
Upvotes: 4
Reputation: 408
recursion is your friend:
function __toObject(Array $arr) {
$obj = new stdClass();
foreach($arr as $key=>$val) {
if (is_array($val)) {
$val = __toObject($val);
}
$obj->$key = $val;
}
return $obj;
}
Upvotes: 7
Reputation: 1480
Using json_encode
is problematic because of the way that it handles non UTF-8 data. It's worth noting that the json_encode
/json_encode
method also leaves non-associative arrays as arrays. This may or may not be what you want. I was recently in the position of needing to recreate the functionality of this solution but without using json_
functions. Here's what I came up with:
/**
* Returns true if the array has only integer keys
*/
function isArrayAssociative(array $array) {
return (bool)count(array_filter(array_keys($array), 'is_string'));
}
/**
* Converts an array to an object, but leaves non-associative arrays as arrays.
* This is the same logic that `json_decode(json_encode($arr), false)` uses.
*/
function arrayToObject(array $array, $maxDepth = 10) {
if($maxDepth == 0) {
return $array;
}
if(isArrayAssociative($array)) {
$newObject = new \stdClass;
foreach ($array as $key => $value) {
if(is_array($value)) {
$newObject->{$key} = arrayToObject($value, $maxDepth - 1);
} else {
$newObject->{$key} = $value;
}
}
return $newObject;
} else {
$newArray = array();
foreach ($array as $value) {
if(is_array($value)) {
$newArray[] = arrayToObject($value, $maxDepth - 1);
} else {
$newArray[] = $value;
}
}
return $newArray;
}
}
Upvotes: 3
Reputation: 762
This function works as same as json_decode(json_encode($arr), false)
.
function arrayToObject(array $arr)
{
$flat = array_keys($arr) === range(0, count($arr) - 1);
$out = $flat ? [] : new \stdClass();
foreach ($arr as $key => $value) {
$temp = is_array($value) ? $this->arrayToObject($value) : $value;
if ($flat) {
$out[] = $temp;
} else {
$out->{$key} = $temp;
}
}
return $out;
}
$arr = ["a", "b", "c"];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));
Output:
array(
0 => 'a',
1 => 'b',
2 => 'c',
)
array(
0 => 'a',
1 => 'b',
2 => 'c',
)
$arr = [["a" => 1], ["a" => 1], ["a" => 1]];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));
Output:
array(
0 => stdClass::__set_state(array('a' => 1,)),
1 => stdClass::__set_state(array('a' => 1,)),
2 => stdClass::__set_state(array('a' => 1,)),
)
array(
0 => stdClass::__set_state(array('a' => 1,)),
1 => stdClass::__set_state(array('a' => 1,)),
2 => stdClass::__set_state(array('a' => 1,)),
)
$arr = ["a" => 1];
var_export(json_decode($arr));
var_export($this->arrayToObject($arr));
Output:
stdClass::__set_state(array('a' => 1,))
stdClass::__set_state(array('a' => 1,))
Upvotes: 1
Reputation: 13298
I would definitly go with a clean way like this :
<?php
class Person {
private $name;
private $age;
private $sexe;
function __construct ($payload)
{
if (is_array($payload))
$this->from_array($payload);
}
public function from_array($array)
{
foreach(get_object_vars($this) as $attrName => $attrValue)
$this->{$attrName} = $array[$attrName];
}
public function say_hi ()
{
print "hi my name is {$this->name}";
}
}
print_r($_POST);
$mike = new Person($_POST);
$mike->say_hi();
?>
if you submit:
you will get this:
I found this more logical comparing the above answers from Objects should be used for the purpose they've been made for (encapsulated cute little objects).
Also using get_object_vars ensure that no extra attributes are created in the manipulated Object (you don't want a car having a family name, nor a person behaving 4 wheels).
Upvotes: 10
Reputation: 198204
Depending on where you need that and how to access the object there are different ways to do it.
For example: just typecast it
$object = (object) $yourArray;
However, the most compatible one is using a utility method (not yet part of PHP) that implements standard PHP casting based on a string that specifies the type (or by ignoring it just de-referencing the value):
/**
* dereference a value and optionally setting its type
*
* @param mixed $mixed
* @param null $type (optional)
*
* @return mixed $mixed set as $type
*/
function rettype($mixed, $type = NULL) {
$type === NULL || settype($mixed, $type);
return $mixed;
}
The usage example in your case (Online Demo):
$yourArray = Array('status' => 'Figure A. ...');
echo rettype($yourArray, 'object')->status; // prints "Figure A. ..."
Upvotes: 25
Reputation: 1078
By using (array) and (object) as prefix, you can simply convert object array to standard array and vice-verse
<?php
//defining an array
$a = array('a'=>'1','b'=>'2','c'=>'3','d'=>'4');
//defining an object array
$obj = new stdClass();
$obj->a = '1';
$obj->b = '2';
$obj->c = '3';
$obj->d = '4';
print_r($a);echo '<br>';
print_r($obj);echo '<br>';
//converting object array to array
$b = (array) $obj;
print_r($b);echo '<br>';
//converting array to object
$c = (object) $a;
print_r($c);echo '<br>';
?>
Upvotes: 0
Reputation: 3820
You could also use an ArrayObject, for example:
<?php
$arr = array("test",
array("one"=>1,"two"=>2,"three"=>3),
array("one"=>1,"two"=>2,"three"=>3)
);
$o = new ArrayObject($arr);
echo $o->offsetGet(2)["two"],"\n";
foreach ($o as $key=>$val){
if (is_array($val)) {
foreach($val as $k => $v) {
echo $k . ' => ' . $v,"\n";
}
}
else
{
echo $val,"\n";
}
}
?>
//Output:
2
test
one => 1
two => 2
three => 3
one => 1
two => 2
three => 3
Upvotes: 8
Reputation: 111
function object_to_array($data)
{
if (is_array($data) || is_object($data))
{
$result = array();
foreach ($data as $key => $value)
{
$result[$key] = object_to_array($value);
}
return $result;
}
return $data;
}
function array_to_object($data)
{
if (is_array($data) || is_object($data))
{
$result= new stdClass();
foreach ($data as $key => $value)
{
$result->$key = array_to_object($value);
}
return $result;
}
return $data;
}
Upvotes: 0
Reputation: 3463
you can simply use type casting to convert an array to object.
// *convert array to object* Array([id]=> 321313[username]=>shahbaz)
$object = (object) $array_name;
//now it is converted to object and you can access it.
echo $object->username;
Upvotes: 181
Reputation: 3250
i have done it with quite simple way,
$list_years = array();
$object = new stdClass();
$object->year_id = 1 ;
$object->year_name = 2001 ;
$list_years[] = $object;
Upvotes: 0
Reputation: 19006
Easy:
$object = json_decode(json_encode($array));
Example:
$array = array(
'key' => array(
'k' => 'value',
),
'group' => array('a', 'b', 'c')
);
$object = json_decode(json_encode($array));
Then, the following is true:
$object->key->k === 'value';
$object->group === array('a', 'b', 'c')
Upvotes: 5
Reputation: 5371
You could also do this by adding (object) on left of variable to create a new object.
<?php
$a = Array
( 'status' => " text" );
var_dump($a);
$b = (object)$a;
var_dump($b);
var_dump($b->status);
Upvotes: 4
Reputation: 404
Inspired by all these codes, i tried to create a enhanced version with support to: specific class name, avoid constructor method, 'beans' pattern and strict mode (set only existing properties):
class Util {
static function arrayToObject($array, $class = 'stdClass', $strict = false) {
if (!is_array($array)) {
return $array;
}
//create an instance of an class without calling class's constructor
$object = unserialize(
sprintf(
'O:%d:"%s":0:{}', strlen($class), $class
)
);
if (is_array($array) && count($array) > 0) {
foreach ($array as $name => $value) {
$name = strtolower(trim($name));
if (!empty($name)) {
if(method_exists($object, 'set'.$name)){
$object->{'set'.$name}(Util::arrayToObject($value));
}else{
if(($strict)){
if(property_exists($class, $name)){
$object->$name = Util::arrayToObject($value);
}
}else{
$object->$name = Util::arrayToObject($value);
}
}
}
}
return $object;
} else {
return FALSE;
}
}
}
Upvotes: 1
Reputation: 14489
Obviously just an extrapolation of some other folks' answers, but here's the recursive function that will convert any mulch-dimensional array into an object:
function convert_array_to_object($array){
$obj= new stdClass();
foreach ($array as $k=> $v) {
if (is_array($v)){
$v = convert_array_to_object($v);
}
$obj->{strtolower($k)} = $v;
}
return $obj;
}
And remember that if the array had numeric keys they can still be referenced in the resulting object by using {}
(for instance: $obj->prop->{4}->prop
)
Upvotes: 2