【问题标题】:php stdClass to arrayphp stdClass 到数组
【发布时间】:2013-09-05 18:31:34
【问题描述】:

我在将对象 stdClass 转换为数组时遇到问题。 我试过这样:

return (array) $booking;

return (array) json_decode($booking,true);

return (array) json_decode($booking);

强制转换之前的数组已满,只有一条记录,在我尝试强制转换后它是空的。 如何在不删除行的情况下进行转换/转换?

投射前的数组:

array(1) {   [0]=>   object(stdClass)#23 (36) {     ["id"]=>     string(1) "2"     ["name"]=>     string(0) ""     ["code"]=>     string(5) "56/13"   } } 

如果我尝试创建var_dump($booking);,则转换后为空 NULL

我也试过这个功能,但总是空:

public function objectToArray($d) {
        if (is_object($d)) {
            // Gets the properties of the given object
            // with get_object_vars function
            $d = get_object_vars($d);
        }

        if (is_array($d)) {
            /*
            * Return array converted to object
            * Using __FUNCTION__ (Magic constant)
            * for recursive call
            */
            return array_map(__FUNCTION__, $d);
        }
        else {
            // Return array
            return $d;
        }
    }

【问题讨论】:

  • php.net/var_dump ... php.net/var_export - 在return 之前。在阵列上运行json_decode 对我来说似乎非常绝望,可能在电脑前坐得太久了,现在该休息一下了?
  • 澄清一下:var_dump($booking); 输出 NULL?
  • 投后是的,如果我尝试打印这个:$booking[0]['id'] 返回我不存在
  • 您可能有兴趣阅读:How to get useful error messages in PHP? - 无论如何,我要求var_dump() 投射之前。顺便说一句,不要重复使用相同的变量名。如果$booking 是投射之前的东西,它应该仍然是 before 投射的东西,而不是之后的东西。输入变量和处理变量之间的差异,否则您会遇到无法再理解的问题。
  • 缩短问题(如删除自定义功能代码)可能有助于查看接受的答案而无需向下滚动

标签: php arrays


【解决方案1】:

惰性单线方法

如果您愿意损失一点性能,您可以使用 JSON 方法在单行中执行此操作(尽管有些人报告它比递归遍历对象更快 - 很可能是因为 PHP 是 slow at calling functions )。 “但我已经这样做了”你说。不完全是——你在数组上使用了json_decode,但你需要先用json_encode对其进行编码。

要求

json_encodejson_decode 方法。这些自动捆绑在 PHP 5.2.0 及更高版本中。如果您使用任何旧版本,还有一个 PECL library(也就是说,在这种情况下,您应该真的更新您的 PHP 安装。对 5.1 的支持在 2006 年停止。)


转换array/stdClass -> stdClass

$stdClass = json_decode(json_encode($booking));

转换array/stdClass -> array

手册将json_decode的第二个参数指定为:

assoc
TRUE时,返回的对象会被转换成关联数组。

因此,以下行会将您的整个对象转换为数组:

$array = json_decode(json_encode($booking), true);

【讨论】:

  • 如果var_dump 中的(array) $booking;NULL(由OP 编写),猜猜这段代码会返回什么?
  • @hakre 将其转换为数组后似乎不是NULL。我认为 OP 意味着在使用 json_decode($array) 之后它是 NULL,这对于 manual 来说是有意义的。 如果无法解码json,则返回NULL
  • @AlessandroMinoccheri 之前它不起作用的原因是在您在数组上使用 json_decode() 之前。 json_decode 应该用于 JSON 字符串。因此,如果我们首先将其编码为 JSON 字符串 (json_encode),然后然后对其进行解码(使用我们的 JSON 字符串),那么它可以正常工作。
  • 大家是否忘记了您将丢失未在 JSON 规范中定义的类型(例如日期)?如果你使用这种方法,那么你需要有一个复兴器。仅当您具有数字、字符串和布尔值等基本类型时,这才有用。
  • 很好的答案,我一直在使用 json_decode($stdClass, true) ;)
【解决方案2】:

使用这个函数来获取你想要的类型的标准数组......

return get_object_vars($booking);

【讨论】:

【解决方案3】:

使用内置的类型转换功能,只需键入

$realArray = (array)$stdClass;

【讨论】:

  • 我更喜欢这个而不是 json_decode/encode,更干净 +1
  • 这个方法更简洁,但是,它也不是递归的,并且与 get_object_vars() 的工作方式相同。虽然 json_decode/encode 方法有一种 hack 的感觉,但它是递归工作的。
【解决方案4】:

因为在你施放它之前它是一个数组,所以施放它是没有意义的。

你可能想要一个递归转换,看起来像这样:

function arrayCastRecursive($array)
{
    if (is_array($array)) {
        foreach ($array as $key => $value) {
            if (is_array($value)) {
                $array[$key] = arrayCastRecursive($value);
            }
            if ($value instanceof stdClass) {
                $array[$key] = arrayCastRecursive((array)$value);
            }
        }
    }
    if ($array instanceof stdClass) {
        return arrayCastRecursive((array)$array);
    }
    return $array;
}

用法:

$obj = new stdClass;
$obj->aaa = 'asdf';
$obj->bbb = 'adsf43';
$arr = array('asdf', array($obj, 3));

var_dump($arr);
$arr = arrayCastRecursive($arr);
var_dump($arr);

之前的结果:

array
    0 => string 'asdf' (length = 4)
  1 => 
    array
        0 =>
        object(stdClass)[1]
          public 'aaa' => string 'asdf' (length = 4)
          public 'bbb' => string 'adsf43' (length = 6)
      1 => int 3

之后的结果:

array
    0 => string 'asdf' (length = 4)
  1 => 
    array
        0 =>
        array
          'aaa' => string 'asdf' (length = 4)
          'bbb' => string 'adsf43' (length = 6)
      1 => int 3

注意:

经过测试并使用复杂的数组,其中一个 stdClass 对象可以包含其他 stdClass 对象。

【讨论】:

  • 太棒了。现在适用于包含 stdClass 对象的 stdClass 对象:)
【解决方案5】:

请使用以下php函数将php stdClass转换为数组

get_object_vars($data)

【讨论】:

  • 注意这个函数不是递归的。请参阅 Carlo Fontanos 的答案以获得递归解决方案。
【解决方案6】:

这个功能对我有用:

function cvf_convert_object_to_array($data) {

    if (is_object($data)) {
        $data = get_object_vars($data);
    }

    if (is_array($data)) {
        return array_map(__FUNCTION__, $data);
    }
    else {
        return $data;
    }
}

参考:http://carlofontanos.com/convert-stdclass-object-to-array-in-php/

【讨论】:

    【解决方案7】:

    刚google了一下,发现here是一个很方便的函数,对于将stdClass对象递归转换为数组很有用。

    <?php
    function object_to_array($object) {
     if (is_object($object)) {
      return array_map(__FUNCTION__, get_object_vars($object));
     } else if (is_array($object)) {
      return array_map(__FUNCTION__, $object);
     } else {
      return $object;
     }
    }
    ?>
    

    编辑:我用来自链接源的内容更新了这个答案(现在也改变了),感谢 mason81 的建议。

    【讨论】:

    • 下次请附上链接来源的相关内容。您提供的链接已更改,现在已不相关且无用。
    • 这就是我要找的东西,非常感谢。
    【解决方案8】:

    这是可在课堂上使用的 Carlo 答案的一个版本:

    class Formatter
    {
        public function objectToArray($data)
        {
            if (is_object($data)) {
                $data = get_object_vars($data);
            }
    
            if (is_array($data)) {
                return array_map(array($this, 'objectToArray'), $data);
            }
    
            return $data;
        }
    }
    

    【讨论】:

      【解决方案9】:

      以下代码将读取所有电子邮件并打印主题、正文和日期。

      <?php
        $imap=imap_open("Mailbox","Email Address","Password");
        if($imap){$fixMessages=1+imap_num_msg($imap);  //Check no.of.msgs
      /*
      By adding 1 to "imap_num_msg($imap)" & starting at $count=1
         the "Start" & "End" non-messages are ignored
      */
          for ($count=1; $count<$fixMessages; $count++){
            $objectOverview=imap_fetch_overview($imap,$count,0);
      print '<br>$objectOverview: '; print_r($objectOverview);
      print '<br>objectSubject ='.($objectOverview[0]->subject));
      print '<br>objectDate ='.($objectOverview[0]->date);
            $bodyMessage=imap_fetchbody($imap,$count,1);
      print '<br>bodyMessage ='.$bodyMessage.'<br><br>';
          }  //for ($count=1; $count<$fixMessages; $count++)
        }  //if($imap)
        imap_close($imap);
      ?>
      

      这会输出以下内容:

      $objectOverview: Array ( [0] => stdClass Object ( [subject] => Hello
      [from] => Email Address [to] => Email Address [date] => Sun, 16 Jul 2017 20:23:18 +0100
      [message_id] =>  [size] => 741 [uid] => 2 [msgno] => 2 [recent] => 0 [flagged] => 0 
      [answered] => 0 [deleted] => 0 [seen] => 1 [draft] => 0 [udate] => 1500232998 ) )
      objectSubject =Hello
      objectDate =Sun, 16 Jul 2017 20:23:18 +0100
      bodyMessage =Test 
      

      在与各种建议作斗争后,我通过反复试验提出了这个解决方案。希望对您有所帮助。

      【讨论】:

        【解决方案10】:

        这是我拥有的最好的 Object to Array 函数 - 递归工作:

        function object_to_array($obj, &$arr){
            
            if(!is_object($obj) && !is_array($obj)){
                $arr = $obj;
                return $arr;
            }
            
            foreach ($obj as $key => $value) {
                if (!empty($value)) {
                    $arr[$key] = array();
                    object_to_array_v2($value, $arr[$key]);
                } else {
                    $arr[$key] = $value;
                }
            }
        
            return $arr;
        }
        
        $clean_array = object_to_array($object_data_here);
        

        【讨论】:

          【解决方案11】:

          这是我在没有 Eloquent 的情况下在 Laravel 中使用它的方法。

          function getUsers(){ 
          
             $users = DB::select('select * from users');       
             $data = json_decode(json_encode($users), true); // to array 
          
             return view('page')->with('data', $data);
          }
          

          【讨论】:

            猜你喜欢
            • 2012-07-08
            • 2014-02-28
            • 2012-05-28
            • 2014-09-19
            • 2016-11-12
            • 2014-10-17
            • 2016-02-04
            • 2012-01-07
            • 2012-11-02
            相关资源
            最近更新 更多