无法将stdClass类型的对象用作数组?


541

使用时出现一个奇怪的错误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']哪里$result返回的数据json_decode()

如何读取此数组中的值?


15
$ result = json_decode('字符串',true); 添加true将结果作为数组而不是stdClass返回。
Nepaluz '16

Answers:



209

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

您可以像这样访问数据:

var_dump($result->context);

如果您有类似from-date的标识符(使用上述方法时,连字符会导致PHP错误),则必须编写以下代码:

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

如果需要数组,可以执行以下操作:

$result = json_decode($json, true);

或将对象转换为数组:

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

2
当我试图找到一种方法来引用敲除js设置的php中的_destroy值时,花了我一段时间来找到它,所以+1
deltree

2
这个答案比第一个(最受好评)的答案更合格!
Mojtaba Rezaeian

149

->因为它是对象,所以您必须使用它。

从以下位置更改代码:

$result['context'];

至:

$result->context;

我遇到的问题是尝试在条件条件下使用该属性,if ($result->context = $var) 这导致该属性被设置为var并返回true,无论如何。
STWilson '16

3
@STWilson您应该使用双精度等于==,在当前状态下,您将使用单精度等于来分配$var值。然后,它将读取它是否为空,如果具有值,则表示它不为空,并且始终返回true。$result->context=if statement$var
JiNexus

89

今天有同样的问题,像这样解决:

如果调用,json_decode($somestring)您将获得一个对象,您需要像这样访问$object->key,但是如果调用,json_decode($somestring, true)您将得到一个字典,并且可以像这样访问$array['key']


2
这为我节省了很多时间!我没有输入true参数,而是尝试将其作为数组访问
Meeyam,



28

正如《PHP手册》所说,

print_r —打印有关变量的可读信息

当使用时json_decode();,我们将获得stdClass类型的对象作为返回类型。要在其中传递的参数print_r()应为数组或字符串。因此,我们无法在中传递对象print_r()。我发现了两种解决方法。

  1. 将对象转换为数组。
    这可以如下实现。

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

    $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


12

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

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

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

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



4

这是函数签名:

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

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

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

错误时将返回NULL。

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


3

有时,使用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>";

预期的输出将是带有换行符的“罗伯特”。

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

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

预期的输出将是带有换行符的“罗伯特”。

要访问下一个键“ 1”,过程相同。

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

预期的输出将是“美国”

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


2

而不是使用括号,而是使用对象运算符,例如,基于数据库对象的数组是在名为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';



?>

然后显示信息,以检查是否设置了服务调用并且计数大于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="https://stackoverflow.com/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'; ?>

2

我突然发现了这个错误,因为我的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对象转换为array 。以下是固定代码。

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

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


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.