【问题标题】:Cannot use object of type stdClass as array?不能将 stdClass 类型的对象用作数组?
【发布时间】:2011-10-12 12:46:00
【问题描述】:

我在使用 json_decode() 时遇到了一个奇怪的错误。它正确解码数据(我使用print_r 看到它),但是当我尝试访问数组内的信息时,我得到:

Fatal error: Cannot use object of type stdClass as array in
C:\Users\Dail\software\abs.php on line 108

我只尝试这样做:$result['context'] 其中$resultjson_decode() 返回的数据

如何读取这个数组中的值?

【问题讨论】:

  • $result = json_decode('字符串', true);添加 true 以数组形式返回结果,而不是 stdClass。
  • 哇,刚刚做了这么大的脸。 xD 已经如此频繁地使用该功能,并且仍然偶然发现该错误。 :D

标签: php json


【解决方案1】:

它不是一个数组,它是一个 stdClass 类型的对象。

你可以这样访问它:

echo $oResult->context;

更多信息在这里:What is stdClass in PHP?

【讨论】:

    【解决方案2】:

    使用true 作为json_decode 的第二个参数。这会将 json 解码为关联数组,而不是 stdObject 实例:

    $my_array = json_decode($my_json, true);
    

    更多详情请见the documentation

    【讨论】:

      【解决方案3】:

      使用json_decode的第二个参数使其返回一个数组:

      $result = json_decode($data, true);
      

      【讨论】:

        【解决方案4】:

        函数json_decode()默认返回一个对象。

        您可以这样访问数据:

        var_dump($result->context);
        

        如果你有像from-date 这样的标识符(使用上述方法时,连字符会导致 PHP 错误)你必须写:

        var_dump($result->{'from-date'});
        

        如果你想要一个数组,你可以这样做:

        $result = json_decode($json, true);
        

        或将对象转换为数组:

        $result = (array) json_decode($json);
        

        【讨论】:

        • 在试图找到一种方法来引用 php 中由 knockoutjs 设置的 _destroy 值时,我花了一段时间才找到这个,所以 +1
        • 这个答案比第一个(评分最高的)答案更合格!
        【解决方案5】:

        不要使用括号,而是使用对象运算符,例如我的基于数据库对象的数组是在一个名为 DB 的类中创建的:

        class DB {
        private static $_instance = null;
        private $_pdo,
                $_query, 
                $_error = false,
                $_results,
                $_count = 0;
        
        
        
        private function __construct() {
            try{
                $this->_pdo = new PDO('mysql:host=' . Config::get('mysql/host') .';dbname=' . Config::get('mysql/db') , Config::get('mysql/username') ,Config::get('mysql/password') );
        
        
            } catch(PDOException $e) {
                $this->_error = true;
                $newsMessage = 'Sorry.  Database is off line';
                $pagetitle = 'Teknikal Tim - Database Error';
                $pagedescription = 'Teknikal Tim Database Error page';
                include_once 'dbdown.html.php';
                exit;
            }
            $headerinc = 'header.html.php';
        }
        
        public static function getInstance() {
            if(!isset(self::$_instance)) {
                self::$_instance = new DB();
            }
        
            return self::$_instance;
        
        }
        
        
            public function query($sql, $params = array()) {
            $this->_error = false;
            if($this->_query = $this->_pdo->prepare($sql)) {
            $x = 1;
                if(count($params)) {
                foreach($params as $param){
                    $this->_query->bindValue($x, $param);
                    $x++;
                    }
                }
            }
            if($this->_query->execute()) {
        
                $this->_results = $this->_query->fetchAll(PDO::FETCH_OBJ);
                $this->_count = $this->_query->rowCount();
        
            }
        
            else{
                $this->_error = true;
            }
        
            return $this;
        }
        
        public function action($action, $table, $where = array()) {
            if(count($where) ===3) {
                $operators = array('=', '>', '<', '>=', '<=');
        
                $field      = $where[0];
                $operator   = $where[1];
                $value      = $where[2];
        
                if(in_array($operator, $operators)) {
                    $sql = "{$action} FROM {$table} WHERE {$field} = ?";
        
                    if(!$this->query($sql, array($value))->error()) {
                    return $this;
                    }
                }
        
            }
            return false;
        }
        
            public function get($table, $where) {
            return $this->action('SELECT *', $table, $where);
        
        public function results() {
            return $this->_results;
        }
        
        public function first() {
            return $this->_results[0];
        }
        
        public function count() {
            return $this->_count;
        }
        
        }
        

        要访问我在控制器脚本上使用此代码的信息:

        <?php
        $pagetitle = 'Teknikal Tim - Service Call Reservation';
        $pagedescription = 'Teknikal Tim Sevice Call Reservation Page';
        require_once $_SERVER['DOCUMENT_ROOT'] .'/core/init.php';
        $newsMessage = 'temp message';
        
        $servicecallsdb = DB::getInstance()->get('tt_service_calls', array('UserID',
         '=','$_SESSION['UserID']));
        
        if(!$servicecallsdb) {
        // $servicecalls[] = array('ID'=>'','ServiceCallDescription'=>'No Service Calls');
        } else {
        $servicecalls = $servicecallsdb->results();
        }
        include 'servicecalls.html.php';
        
        
        
        ?>
        

        然后显示信息,我检查是否已设置 servicecalls 并且计数是否大于 0 记住它不是我引用的数组,所以我使用对象运算符“->”访问记录,如下所示:

        <?php include $_SERVER['DOCUMENT_ROOT'] .'/includes/header.html.php';?>
        <!--Main content-->
        <div id="mainholder"> <!-- div so that page footer can have a minum height from the
          header -->
        <h1><?php if(isset($pagetitle)) htmlout($pagetitle);?></h1>
        <br>
        <br>
        <article>
            <h2></h2>
        </article>
        <?php
        if (isset($servicecalls)) {
        if (count ($servicecalls) > 0){
             foreach ($servicecalls as $servicecall) {
                echo '<a href="/servicecalls/?servicecall=' .$servicecall->ID .'">'
          .$servicecall->ServiceCallDescription .'</a>';
            }
        }else echo 'No service Calls';
        
        }
        
        ?>
        <a href="/servicecalls/?new=true">Raise New Service Call</a>
        </div> <!-- Main content end-->
        <?php include $_SERVER['DOCUMENT_ROOT'] .'/includes/footer.html.php'; ?>
        

        【讨论】:

        • 对一个简单问题的回答太长了。
        【解决方案6】:

        您必须使用 -&gt; 访问它,因为它是一个对象。

        从以下位置更改您的代码:

        $result['context'];
        

        收件人:

        $result->context;
        

        【讨论】:

        • 我遇到的问题是尝试在条件 if ($result-&gt;context = $var) 中使用该属性,这会导致该属性设置为 var 并返回 true,无论如何。
        • @STWilson 您应该使用双等号==,在当前状态下,您通过使用单等号=$var 值分配给$result-&gt;contextif statement 将读取它,就好像它是否为空一样,如果 $var 有值,则意味着它不为空,并且将始终返回 true。
        • 为什么这个页面似乎表明两种语法都允许:php.net/manual/en/sdo.sample.getset.php
        • @kojow7 如果您指的是$company-&gt;departments[0]-&gt;name,那是因为它使用数组索引直接访问对象。数据的结构是,对象存储在数组中。
        • @JiNexus 我的意思是该页面上的示例 #1 和 #2。 Example #1 说你可以使用:$company-&gt;name = 'Acme';,Example #2 说你可以使用:$company['name'] = 'UltraCorp';
        【解决方案7】:

        您可以将 stdClass 对象转换为数组,例如:

        $array = (array)$stdClass;
        

        stdClsss to array

        【讨论】:

          【解决方案8】:

          这是函数签名:

          mixed json_decode ( string $json [, bool $assoc = false [, int $depth = 512 [, int $options = 0 ]]] )
          

          当 param 为 false(默认)时,它将返回适当的 php 类型。您使用 object.method 范例获取该类型的值。

          当 param 为 true 时,它​​会返回关联数组。

          出错时返回 NULL。

          如果要通过数组获取值,请将 assoc 设置为 true。

          【讨论】:

            【解决方案9】:

            今天遇到同样的问题,这样解决:

            如果你调用json_decode($somestring),你会得到一个对象,你需要像$object-&gt;key一样访问,但是如果你调用json_decode($somestring, true),你会得到一个字典,并且可以像$array['key']一样访问

            【讨论】:

            • 这为我节省了很多时间!我没有输入 true 参数,而是尝试将其作为数组访问
            • 我以前遇到过这个问题,这也是当时的解决方案,谢谢它是如此简单的修复
            • 救命!尤其是echo json_decode('{"Contains Space":999}', true)['Contains Space'] . "\n";
            【解决方案10】:

            正如 Php 手册所说,

            print_r — 打印关于变量的人类可读信息

            当我们使用json_decode(); 时,我们得到一个stdClass 类型的对象作为返回类型。 在print_r() 中传递的参数应该是数组或字符串。因此,我们不能在print_r() 中传递对象。我找到了两种方法来解决这个问题。

            1. 将对象转换为数组。
              这可以通过以下方式实现。

              $a = (array)$object;
              
            2. 通过访问对象的键
              如前所述,当你使用json_decode(); 函数时,它返回一个stdClass 的Object。您可以在-&gt; Operator 的帮助下访问对象的元素。

              $value = $object->key;
              

            一,如果对象有嵌套数组,也可以使用多个键来提取子元素。

            $value = $object->key1->key2->key3...;
            

            它们也是print_r() 的其他选项,例如var_dump();var_export();

            PS:另外,如果将json_decode();的第二个参数设置为true,它会自动将对象转换为array();
            这里有一些参考资料:
            http://php.net/manual/en/function.print-r.php
            http://php.net/manual/en/function.var-dump.php
            http://php.net/manual/en/function.var-export.php

            【讨论】:

              【解决方案11】:

              当您尝试以$result['context'] 访问它时,您将其视为一个数组,错误告诉您您实际上正在处理一个对象,那么您应该以$result-&gt;context 访问它

              【讨论】:

                【解决方案12】:

                改成

                $results->fetch_array()
                

                【讨论】:

                • 你的意思是mysqli_result::fetch_array?这似乎与问题无关。
                【解决方案13】:

                我突然收到了这个错误,因为我的 Facebook 登录突然停止工作(我也更换了主机)并抛出了这个错误。修复很简单

                问题出在这段代码中

                  $response = (new FacebookRequest(
                    FacebookSession::newAppSession($this->appId, $this->appSecret),
                    'GET',
                    '/oauth/access_token',
                    $params
                  ))->execute()->getResponse(true);
                
                  if (isset($response['access_token'])) {       <---- this line gave error
                    return new FacebookSession($response['access_token']);
                  }
                

                基本上 isset() 函数需要一个数组,但它会找到一个对象。简单的解决方案是使用 (array) 量词将 PHP 对象转换为数组。以下是固定代码。

                  $response = (array) (new FacebookRequest(
                    FacebookSession::newAppSession($this->appId, $this->appSecret),
                    'GET',
                    '/oauth/access_token',
                    $params
                  ))->execute()->getResponse(true);
                

                注意在第一行使用 off array() 量词。

                【讨论】:

                  【解决方案14】:

                  要从 json 字符串中获取数组,您应该将第二个参数设置为 boolean true。

                  $result = json_decode($json_string, true);
                  $context = $result['context'];
                  

                  否则 $result 将是一个 std 对象。但您可以将值作为对象访问。

                    $result = json_decode($json_string);
                   $context = $result->context;
                  

                  【讨论】:

                    【解决方案15】:

                    有时在使用 API 时,您只想将对象保留为对象。要访问具有嵌套对象的对象,您可以执行以下操作:

                    我们假设当您 print_r 对象时您可能会看到:

                    print_r($response);
                    
                    stdClass object
                    (
                        [status] => success
                        [message] => Some message from the data
                        [0] => stdClass object
                            (
                                [first] => Robert
                                [last] => Saylor
                                [title] => Symfony Developer
                            )
                        [1] => stdClass object
                            (
                                [country] => USA
                            )
                    )
                    

                    访问对象的第一部分:

                    print $response->{'status'};
                    

                    这将输出“成功”

                    现在让我们键入其他部分:

                    $first = $response->{0}->{'first'};
                    print "First name: {$first}<br>";
                    

                    预期的输出将是带有换行符的“Robert”。

                    您还可以将对象的一部分重新分配给另一个对象。

                    $contact = $response->{0};
                    print "First Name: " . $contact->{'first'} . "<br>";
                    

                    预期的输出将是带有换行符的“Robert”。

                    访问下一个键“1”的过程是相同的。

                    print "Country: " . $response->{1}->{'country'} . "<br>";
                    

                    预期的输出将是“美国”

                    希望这将帮助您理解对象以及我们为什么要将对象保留为对象。您无需将对象转换为数组即可访问其属性。

                    【讨论】:

                      【解决方案16】:

                      试试这个!

                      而不是像这样获取上下文:(这适用于获取数组索引)

                      $result['context']
                      

                      尝试(此工作用于获取对象)

                      $result->context
                      

                      其他例子是:(如果$result有多个数据值)

                      Array
                      (
                          [0] => stdClass Object
                              (
                                  [id] => 15
                                  [name] => 1 Pc Meal
                                  [context] => 5
                                  [restaurant_id] => 2
                                  [items] => 
                                  [details] => 1 Thigh (or 2 Drums) along with Taters
                                  [nutrition_fact] => {"":""}
                                  [servings] => menu
                                  [availability] => 1
                                  [has_discount] => {"menu":0}
                                  [price] => {"menu":"8.03"}
                                  [discounted_price] => {"menu":""}
                                  [thumbnail] => YPenWSkFZm2BrJT4637o.jpg
                                  [slug] => 1-pc-meal
                                  [created_at] => 1612290600
                                  [updated_at] => 1612463400
                              )
                      
                      )
                      

                      然后试试这个:

                      foreach($result as $results)
                      {
                            $results->context;
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2012-03-29
                        • 2011-09-04
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        • 2021-12-17
                        相关资源
                        最近更新 更多