如何在PHP中将数组转换为对象?

488

我该如何将这样的数组转换为对象?

[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"
    )

4
您希望获得什么样的物品,具体来说是指它应该具备哪些属性? - Pascal MARTIN
在循环中,应该同时打印两个,因为状态是一个数据数组,所以两个都被打印。 - streetparade
3
不确定从什么时候开始,但这段代码有效:$a = (object)['hello' => 'world']; - user1267177
35个回答

5

简单:

$object = json_decode(json_encode($array));

例子:

$array = array(
    'key' => array(
        'k' => 'value',
    ),
    'group' => array('a', 'b', 'c')
);

$object = json_decode(json_encode($array));

那么,以下内容是正确的:

$object->key->k === 'value';
$object->group === array('a', 'b', 'c')

1
我认为这是一个变通的方法。为什么要将数组编码为JSON,然后再解码呢?对我来说,这不是最优的决策。 - Julian
1
@Julian,因为它可以递归地工作,在定义良好且足够可靠(“标准”)的方式下运行,并且速度足够快,是随意手动编码的好替代品。 - Sz.

4
世界上最好的方法 :)
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;
    }
}

如果你使用不同的方法,就会遇到问题。这是最好的方法,你从未见过。


4
你可以在变量左边添加(object)来创建一个新的对象。
<?php
$a = Array
    ( 'status' => " text" );
var_dump($a);
$b = (object)$a;
var_dump($b);
var_dump($b->status);

http://codepad.org/9YmD1KsU


1
也许值得一提的是,这被称为“强制转换”或“类型转换”:http://www.php.net/manual/en/language.types.type-juggling.php#language.types.typecasting,而(object)array()的行为在此处有所记录:http://www.php.net/manual/en/language.types.object.php#language.types.object.casting。 - Pete

3

使用json_encode存在问题,因为它处理非UTF-8数据的方式。值得注意的是,json_encode/json_encode方法也会将非关联数组保留为数组。这可能是您想要的,也可能不是您想要的。最近我需要重新创建此解决方案的功能,但不能使用json_函数。以下是我的解决方法:

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

3
您可以使用反射技术:
<?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);

3

将多维数组转化为对象。这段代码用于将Bing搜索API的try和catch方法进行转换。

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

2

显然,这只是其他人答案的推断,但是下面是递归函数,可以将任何多维数组转换为对象:

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

请记住,如果数组中有数字键,则仍然可以使用{}在生成的对象中引用它们(例如:$obj->prop->{4}->prop)。


1
受到所有这些代码的启发,我尝试创建一个增强版,支持:特定类名、避免构造方法、'beans'模式和严格模式(仅设置现有属性)。
    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;
        }
        }
}

1
CakePHP有一个递归的Set::map类,基本上将数组映射到对象中。您可能需要更改数组的外观,以使对象看起来符合您的要求。

http://api.cakephp.org/view_source/set/#line-158

最坏的情况下,您可能会从这个函数中得到一些想法。

1

编程

这个函数的作用与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;
}

测试

测试1:扁平数组

$arr = ["a", "b", "c"];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));

输出:

array(
    0 => 'a',
    1 => 'b',
    2 => 'c',
)
array(
    0 => 'a',
    1 => 'b',
    2 => 'c',
)

测试2:对象数组
$arr = [["a" => 1], ["a" => 1], ["a" => 1]];
var_export(json_decode(json_encode($arr)));
var_export($this->arrayToObject($arr));

输出:

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

测试 3:对象
$arr = ["a" => 1];
var_export(json_decode($arr));
var_export($this->arrayToObject($arr));

输出:

stdClass::__set_state(array('a' => 1,))
stdClass::__set_state(array('a' => 1,))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接