Не можете использовать объект типа stdClass в качестве массива?

340

Я получаю странную ошибку, используя 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()

Как читать значения внутри этого массива?

  • 14
    $ result = json_decode ('the string', true); Добавление true возвращает результат в виде массива, а не stdClass.
Теги:

13 ответов

562

Используйте второй параметр json_decode, чтобы вернуть массив:

$result = json_decode($data, true);
162

Функция 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
    Мне понадобилось некоторое время, чтобы найти это, когда я пытался найти способ обратиться к значению _destroy в php, которое устанавливается knockoutjs, так что +1
  • 1
    Этот ответ гораздо более квалифицирован, чем первый (самый рейтинговый) ответ!
95

Вы должны получить к нему доступ с помощью -> с момента его создания.

Измените свой код:

$result['context'];

To:

$result->context;
  • 0
    Проблема, которую я имею, пытается использовать свойство в условном if ($result->context = $var) Это приводит к тому, что для свойства устанавливается значение var, и возвращается значение true, неважно.
  • 1
    @STWilson вы должны использовать двойное равенство == , в своем текущем состоянии вы присваиваете значение $var для $result->context с помощью одного равного = . И if statement будет читать его так, как если бы он был пустым или нет, и если $var имеет значение, то это означает, что он не пустой и всегда будет возвращать true.
Показать ещё 1 комментарий
59

Используйте true как второй параметр для json_decode. Это расшифровывает json в ассоциативный массив вместо экземпляров stdObject:

$my_array = json_decode($my_json, true);

Подробнее см. документацию.

38

Это не массив, это объект типа stdClass.

Доступ к нему можно получить следующим образом:

echo $oResult->context;

Подробнее здесь: Что такое stdClass в PHP?

  • 0
    Спасибо! brogrammer.
22

Иметь такую ​​же проблему сегодня, решить вот так:

Если вы вызываете json_decode($somestring), вы получите объект, и вам нужно получить доступ, например, $object->key, но если u call json_decode($somestring, true), вы получите словарь и сможете получить доступ, например, $array['key']

  • 1
    Это сэкономило мне ооочень много времени! Я не вводил истинный параметр, а пытался получить к нему доступ в виде массива
16

Как говорится в Php Manual,

print_r - печатает удобочитаемую информацию о переменной -

Когда мы используем json_decode();, мы получаем объект типа stdClass как возвращаемый тип. Аргументы, которые должны быть переданы внутри print_r(), должны быть либо массивом, либо строкой. Следовательно, мы не можем передать объект внутри print_r(). Я нашел 2 способа справиться с этим.

  • Передача объекта в массив.
    Это можно сделать следующим образом.

    $a = (array)$object;
    
  • Доступ к ключу объекта
    Как упоминалось ранее, когда вы используете функцию json_decode();, она возвращает объект stdClass. вы можете получить доступ к элементам объекта с помощью -> Operator.

    $value = $object->key;
    

Один, также может использовать несколько ключей для извлечения подэлементов, если объект имеет вложенные массивы.

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

Это другие варианты print_r(), например var_dump(); и var_export();

P.S: Кроме того, если вы установите второй параметр 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

6

Вы можете преобразовать объект stdClass в массив, например:

$array = (array)$stdClass;

stdClsss для массива

4

Когда вы пытаетесь получить к нему доступ как $result['context'], вы рассматриваете его как массив, то это говорит о том, что вы на самом деле имеете дело с объектом, тогда вы должны получить к нему доступ как $result->context

4

Вот подпись функции:

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

Если параметр равен false, который по умолчанию, он вернет соответствующий тип php. Вы получаете значение этого типа с использованием парадигмы object.method.

Если параметр равен true, он возвратит ассоциативные массивы.

Он вернет NULL при ошибке.

Если вы хотите получить значение через массив, установите для него значение true.

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() ожидает массив, но вместо этого находит объект. Простым решением является преобразование объекта PHP в массив с использованием квантора (массив). Ниже приведен фиксированный код.

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

Обратите внимание на использование байта блока array() в первой строке.

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

}

для доступа к информации я использую этот код на контроллере script:

<?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'; ?>
0

Измените его для

$results->fetch_array()

Ещё вопросы

Сообщество Overcoder
Наверх
Меню