streetparade
streetparade

Reputation: 32908

How to convert an array to object in PHP?

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

Answers (30)

Dixit
Dixit

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

PHZ.fi-Pharazon
PHZ.fi-Pharazon

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

Uchephilz
Uchephilz

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

Noha Shehab
Noha Shehab

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

celsowm
celsowm

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

Krishnamoorthy Acharya
Krishnamoorthy Acharya

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

Ankit Vishwakarma
Ankit Vishwakarma

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

TimSparrow
TimSparrow

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

Chris Jeffries
Chris Jeffries

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

johannes
johannes

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

YesItsMe
YesItsMe

Reputation: 1789

one liner

$object= json_decode(json_encode($result_array, JSON_FORCE_OBJECT));

Upvotes: 7

Douraid Arfaoui
Douraid Arfaoui

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

Julius F
Julius F

Reputation: 3444

Here are three ways:

  1. 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;
        }
    }
    
  2. Convert the array into an object by casting it to an object:

    $array = array(
        // ...
    );
    $object = (object) $array;
    
  3. Manually convert the array into an object:

    $object = object;
    foreach ($arr as $key => $value) {
        $object->{$key} = $value;
    }
    

Upvotes: 106

Tschallacka
Tschallacka

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

jlb
jlb

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

Zezeron
Zezeron

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

anwar
anwar

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

DavidH
DavidH

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

acelot
acelot

Reputation: 762

Code

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;
}

Testing

Test 1: Flat array

$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',
)

Test 2: Array of objects

$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,)),
)

Test 3: Object

$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

vdegenne
vdegenne

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:

formulaire

you will get this:

mike

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

hakre
hakre

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

VishnuPrasad
VishnuPrasad

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

slevy1
slevy1

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

Mehmet Ali Ulusan
Mehmet Ali Ulusan

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

Shahbaz
Shahbaz

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

Muhammad
Muhammad

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

Eduardo Cuomo
Eduardo Cuomo

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

fedmich
fedmich

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);

http://codepad.org/9YmD1KsU

Upvotes: 4

celsowm
celsowm

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

Ben D
Ben D

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

Related Questions