【问题标题】:Initialize Objects like arrays in PHP?在 PHP 中初始化像数组这样的对象?
【发布时间】:2010-12-16 20:50:19
【问题描述】:

在 PHP 中,您可以使用以下符号快速初始化数组:

$array = array("name" => "member 1", array("name" => "member 1.1") ) ....

有什么方法可以对 STDClass 对象执行此操作吗? 我不知道还有什么比沉闷更短的方法

$object = new STDClass();
$object->member1 = "hello, I'm 1";
$object->member1->member1 = "hello, I'm 1.1";
$object->member2 = "hello, I'm 2";

【问题讨论】:

  • 你应该把“正确的勾号”从 Tim 改成 Dumbo 的答案
  • @mrzmyr,小飞象还是秋葵?
  • @Pacerier 对不起,我的意思是秋葵 :)

标签: php


【解决方案1】:

来自 (post) 显示类型转换和使用递归函数将单维和多维数组转换为标准对象:

<?php
function arrayToObject($array) {
    if (!is_array($array)) {
        return $array;
    }
  
    $object = new stdClass();
    if (is_array($array) && count($array) > 0) {
        foreach ($array as $name=>$value) {
            $name = strtolower(trim($name));
            if (!empty($name)) {
                $object->$name = arrayToObject($value);
            }
        }
        return $object;
    }
    else {
        return FALSE;
    }
}

本质上,您构造了一个接受$array 并遍历其所有键和值的函数。它使用键将值分配给类属性。

如果一个值是一个数组,则再次(递归)调用该函数,并将其输出分配为该值。

上面的示例函数正是这样做的;但是,逻辑的顺序可能与您自然想到的过程有点不同。

【讨论】:

  • 我要的是多维数组,就这样吧。谢谢。
  • 目前,我将只使用类型转换。从长远来看,我会在 gnud 和这个答案之间进行混合:一个可以递归工作的dumb_container 对象。谢谢大家。
  • 你能把这个答案扩展到这里吗?链接可能已失效。
  • 链接实际上已经死了!
【解决方案2】:

来自this 对类似问题的回答:

从 PHP7 开始,我们有 Anonymous Classes,它允许您在运行时扩展一个类,包括设置其他属性:

$a = new class() extends MyObject {
    public $property1 = 1;
    public $property2 = 2;
};

echo $a->property1; // prints 1

它不像数组的初始化那样简洁。不确定我是否会使用它。但它您可以考虑的另一种选择。

【讨论】:

    【解决方案3】:

    deep 转换的另一个选项是使用json_encode + json_decode(默认解码为stdClass)。这样您就不必在每个嵌套对象中重复 (object) 转换。

    $object = json_decode(json_encode(array(
         'member1' => "hello, I'm 1",
         'member1o' => array(
             'member1' => "hello, I'm 1o.1",
         ),
         'member2' => "hello, I'm 2",
    )));
    

    输出:

    php > print_r($object);
    stdClass Object
    (
        [member1] => hello, I'm 1
        [member1o] => stdClass Object
            (
                [member1] => hello, I'm 1o.1
            )
    
        [member2] => hello, I'm 2
    )
    

    【讨论】:

    • 但是空数组仍然被视为数组。
    【解决方案4】:

    你可以使用:

    $object = (object)[]; // shorter version of (object)array();
    
    $object->foo = 'bar';
    

    【讨论】:

      【解决方案5】:

      我也投票赞成 Gumbo 作为首选解决方案,但他的建议与所要求的并不完全相同,这可能会导致一些混淆,为什么 member1o 看起来更像 member1a

      为了确保这一点现在很清楚,这两种方式(自 5.4 以来现在是 3 种方式)在 php 中生成相同的stdClass

      1. 根据问题的长期或手动方法:

        $object = new stdClass;
        $object->member1 = "hello, I'm 1";
        $object->member1o = new stdClass;
        $object->member1o->member1 = "hello, I'm 1o.1";
        $object->member2 = "hello, I'm 2";
        
      2. Ala Gumbo 的建议,用于从数组中投射对象的较短或单行版本(为了清楚起见,在此处进行了扩展)。

        $object = (object)array(
             'member1' => "hello, I'm 1",
             'member1o' => (object)array(
                 'member1' => "hello, I'm 1o.1",
             ),
             'member2' => "hello, I'm 2",
        );
        
      3. PHP 5.4+ 缩短的数组声明样式

        $object = (object)[
             'member1' => "hello, I'm 1",
             'member1o' => (object)['member1' => "hello, I'm 1o.1"],
             'member2' => "hello, I'm 2",
        ];
        

      两者都会产生完全相同的结果:

      stdClass Object
      (
          [member1] => hello, I'm 1
          [member1o] => stdClass Object
              (
                  [member1] => hello, I'm 1o.1
              )
      
          [member2] => hello, I'm 2
      )
      

      快乐!

      【讨论】:

      • 优秀的总结。需要注意的是 member1o 需要与 memeber1 字符串不同
      • 感谢您的详尽总结。希望这能被接受!
      【解决方案6】:

      你可以试试:

      function initStdClass($thing) {
          if (is_array($thing)) {
            return (object) array_map(__FUNCTION__, $thing);
          }
          return $thing;
      }
      

      【讨论】:

      • 使用__FUNCTION__ 获得更大的灵活性。
      • 完成。 ⁡⁢⁣⁠⁠⁠⁡
      【解决方案7】:

      我使用了一个名为 Dict 的类:

      class Dict {
      
          public function __construct($values = array()) {
              foreach($values as $k => $v) {
                  $this->{$k} = $v;
              }
          }
      }
      

      它还具有与其他对象和数组合并的功能,但这有点超出了这个问题的范围。

      【讨论】:

        【解决方案8】:

        你可以使用类型转换:

        $object = (object) array("name" => "member 1", array("name" => "member 1.1") );
        

        【讨论】:

        • 虽然我个人建议实际上让你的类做一些事情,并使用数组作为“哑容器”,但这是这样做的方法。
        • Jani,你说得有道理,但我只是 喜欢 以 -> 方式寻址容器。 :)
        • 干杯,我不知道这很容易 - 至少对于一维的。
        • @Gumbo,这不适用于一维以上。最简单的解决方案是编写我们自己的函数来扩展它。
        • 这可能在 second array 之前也应该有 (object)。请参阅@nickl- 的回答。
        猜你喜欢
        • 2020-03-19
        • 2018-06-22
        • 1970-01-01
        • 2017-02-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多