如何在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个回答

802
在最简单的情况下,可能只需要将数组“强制转换”为对象即可:
$object = (object) $array;

另一个选项是将标准类实例化为变量,并在遍历数组时重新分配值:

$object = new stdClass();
foreach ($array as $key => $value)
{
    $object->$key = $value;
}

正如Edson Medina所指出的,一个真正简洁的解决方案是使用内置的json_函数:

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

这也会(递归地)将所有子数组转换为对象,这可能是您想要的,也可能不是。不幸的是,它与循环方法相比有2-3倍的性能损失

警告!(感谢Ultra的评论):

在不同环境下进行json_decode时以不同方式转换UTF-8数据。我最终在本地得到一个值为“240.00”,而在生产环境中得到“240”-非常糟糕。此外,如果转换失败,字符串将返回为空。


46
“由于变量不能以数字开头”,是错误的,实际上可以:$object->{3} = 'xyz'; - chelmertz
13
“has a 2-3x performance hit” 的翻译是“性能下降了2到3倍”,但这个比较不公平,因为后一种方法返回递归对象,而没有进一步的条件(如@streetparade的答案中),只转换第一层。 - feeela
10
@feeela,我认为这一点也不不公平。我已经提到它会递归地进行转换。此外,2-3倍的性能损失是使用一个扁平输入数组得出的(这不会使用任何递归)。 - jlb
9
警告!在不同环境下使用json_decode会以不同的方式转换UTF-8数据。我最终在本地得到了'240.00'和在生产环境中得到了'240'两个值——这是一个巨大的灾难。此外,如果转换失败,字符串将返回为NULL。 - Szymon Toda
2
在使用json_*函数时请注意:原始数组中存储的引用(例如对其他数组的引用)将在此情况下被复制。假设数组中的关键字x保存了对另一个数组的引用。那么,在执行一行代码后,$object->x将是$array['x']的副本,不再是对原始数组的引用。这在某些应用程序中可能是无害的,但对于大型数组来说,这会浪费内存,并且如果稍后使用引用,则可能会混乱执行。 - The Coprolal
显示剩余5条评论

180

您可以使用类型转换将数组转换为对象。

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

你是真正的英雄。 - myckhel

165

简单的方法是

$object = (object)$array;

但这不是你想要的。如果你想要对象,你需要实现某些功能,但这个问题缺失了这些信息。仅仅为了使用而使用对象是没有意义的。


2
不起作用,我在发问之前已经尝试过了,所以肯定还有其他方法可以做到。 - streetparade
30
他为什么要说明想要使用对象的原因?我认为这与具体“如何”完成任务无关。也许他需要将它们进行json编码或序列化?有很多原因需要这样做。 - zombat
嗯...我看了一下浏览器输出,它看起来像这样: object(stdClass)#150 (130) { [0]=> array(1) { ["status"]=> string(130) "At long last Mac and Linux users don't have to feel like second class citizens in Chrome land: they've got official beta versio…" } } 官方上说这是一个对象,但如何遍历它以便我可以像 $obj->status 这样访问 status?有什么想法吗? - streetparade
zombat,使用JSON编码不是使用对象的理由,json_encode()有一个标志可以使用对象。使用序列化需要接收方期望的特定对象类型。总的来说,我尝试帮助解决实际问题。对我来说,这个问题意味着在其他地方存在架构错误。 - johannes
1
旧的对话,但有时我只使用对象,因为我更喜欢$o->thing而不是$a["thing"]。 - senecaTheMeek

126

快速解决办法:

// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);

不太美观,但有效。


2
我真的很喜欢这个解决方案,使用内置函数而不是用户定义的函数总是更快的,而且这个功能非常好。谢谢你的提示。 - aknatn
1
@Oddant,为了公正对待@EdsonMedina,原问题并没有指定属性需要什么可见性,并且由于OP在后面的评论中没有使用$this作为访问器,因此强烈暗示他/她希望输出一个stdClass实例而不是像你的答案所使用的用户定义类。我同意这种解决方案的优雅性,但不幸的是,在解决这个问题时使用嵌套数组的模式是相当常见的。另外,OP可能正在使用需要对象作为输入而不是数组的接口。 - DeaconDesperado
3
请记住,如果使用这种方式,您将失去除基本类型之外的所有内容。例如,DateTime将被转换为stdObject。 - Denis Pshenov
1
@JohnDoe 这个问题是指关联数组,而不是简单数组。 - Edson Medina
1
@EdsonMedina 是的,我知道。如果你搜索将数组转换为对象,这个问题是谷歌上最早的结果之一。所以我认为这个细节对某些人来说可能很重要。特别是原始的数组来自于操作员,这表明答案也可能适用于简单的数组。 - John Doe
显示剩余3条评论

106

以下是三种方法:

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

2
谢谢,但是您的face类出现了以下错误:致命错误:无法在/var/www/bot/inc/twitter-bot.php的第10行重新分配$this。 - streetparade
1
类型转换和 typcasting @ reference 不是一个好主意,即使它不起作用。 这是我得到的: 意外的 T_OBJECT_CAST,期望 T_NEW 或 T_STRING 或 T_VARIABLE 或 '$'。 - streetparade
2
$array =& (object) $array 是一个不错的 KISS 实现! - mate64
17
为什么会有人想使用不同于2)的方法?是否存在任何缺点? - Yogu
9
将一个数组强制转换为对象,对于嵌套数组是无效的。 - MinhajulAnwar
显示剩余2条评论

50
这太简单了,这也会为递归数组创建一个对象。
$object = json_decode(json_encode((object) $yourArray), FALSE);

4
false 作为参数传递给 json_decode() 函数会返回一个关联数组。 - Rusty
9
true传递给json_decode会返回一个关联数组,false是默认值并会返回一个StdClass实例。 - Elliot Reed
看起来像是 https://stackoverflow.com/a/9895734/2943403 的一个晚期副本 - undefined

30

我也遇到了这个问题,但我注意到json_decode将JSON数组转换为对象。

所以,我通过使用json_encode($ PHPArray)获得解决方案,它返回一个对象的JSON字符串,然后我使用Json_decode($ string)解码字符串,它将返回一个完美结构化的对象。 简写

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

或者

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

JSON对象 - Alex78191

25
你可以使用(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);
结果将是一个包含数组的对象:

object(stdClass)#1048 (2) { [128]=> array(1) {

["status"]=> string(87) "图A。Facebook在1024x768屏幕分辨率上显示水平滚动条。" }

[129]=> array(1) { ["status"]=> string(44) "前几天在工作中,我有一些空闲时间。" } }


2
这里(对象)不是一个函数,你只是进行了类型转换。 - habib
严格来讲,这不是类型转换,因为你改变的是的类型,而不是变量的类型。请参见https://dev59.com/QHM_5IYBdhLWcg3w9oaG#1147377 - Ari Cooper-Davis

25

根据您需要的位置和访问对象的方式,有不同的方法可以实现。

例如:只需进行类型转换即可。

$object =  (object) $yourArray;

然而,最兼容的方法是使用一个实用程序方法(尚未成为 PHP 的一部分),该方法基于指定类型的字符串(或者忽略它只是取消引用值)来实现标准的 PHP 强制类型转换:

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

您的情况中的用法示例(在线演示):

$yourArray = Array('status' => 'Figure A. ...');

echo rettype($yourArray, 'object')->status; // prints "Figure A. ..."

24

这个对我有用

  function array_to_obj($array, &$obj)
  {
    foreach ($array as $key => $value)
    {
      if (is_array($value))
      {
      $obj->$key = new stdClass();
      array_to_obj($value, $obj->$key);
      }
      else
      {
        $obj->$key = $value;
      }
    }
  return $obj;
  }

function arrayToObject($array)
{
 $object= new stdClass();
 return array_to_obj($array,$object);
}

用法:

$myobject = arrayToObject($array);
print_r($myobject);

返回值:

    [127] => stdClass Object
        (
            [status] => Have you ever created a really great looking website design
        )

    [128] => stdClass Object
        (
            [status] => Figure A.
 Facebook's horizontal scrollbars showing up on a 1024x768 screen resolution.
        )

    [129] => stdClass Object
        (
            [status] => The other day at work, I had some spare time
        )

就像往常一样,您可以像这样循环它:

foreach($myobject as $obj)
{
  echo $obj->status;
}

但是这个方法比类型转换慢了大约500%(经过测试):$obj = (object) $array; - xZero
1
@xZero 但是 $obj = (object) $array; 对于多维数组不起作用。 - Jeff Puckett

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