Nie można użyć obiektu typu stdClass jako tablicy?

541

Podczas używania pojawia się dziwny błąd json_decode(). Prawidłowo dekoduje dane (widziałem to za pomocą print_r), ale kiedy próbuję uzyskać dostęp do informacji w tablicy, otrzymuję:

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

Próbowałem tylko: $result['context']gdzie $resultsą zwracane danejson_decode()

Jak mogę odczytać wartości w tej tablicy?

Dail
źródło
15
$ result = json_decode („ciąg”, prawda); Dodanie wartości true zwraca wynik jako tablicę, a nie jako stdClass.
Nepaluz

Odpowiedzi:

788

Użyj drugiego parametru, json_decodeaby zwrócić tablicę:

$result = json_decode($data, true);
Jon
źródło
209

Funkcja json_decode()domyślnie zwraca obiekt.

Możesz uzyskać dostęp do takich danych:

var_dump($result->context);

Jeśli masz identyfikatory takie jak from-date(łącznik spowodowałby błąd PHP podczas korzystania z powyższej metody), musisz napisać:

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

Jeśli chcesz tablicę, możesz zrobić coś takiego:

$result = json_decode($json, true);

Lub rzutuj obiekt na tablicę:

$result = (array) json_decode($json);
svens
źródło
2
zajęło mi trochę czasu, aby to znaleźć, próbując znaleźć sposób na odniesienie się do wartości _destroy w php ustawionej przez knockoutjs, więc +1
deltree
2
Ta odpowiedź jest znacznie bardziej wykwalifikowana niż pierwsza (najczęściej oceniana) odpowiedź!
Mojtaba Rezaeian,
149

Musisz uzyskać do niego dostęp, ->ponieważ jest to obiekt.

Zmień kod z:

$result['context'];

Do:

$result->context;
JiNexus
źródło
Problem, który mam, polega na próbie użycia właściwości w warunku. if ($result->context = $var) To powoduje, że właściwość jest ustawiona na var i zwraca true, bez względu na to.
STWilson,
3
@STWilson powinieneś używać podwójnej równości ==, w obecnym stanie przypisujesz $varwartość $result->contextużywając pojedynczej równości =. A if statementczytają to tak, jakby było puste, czy nie, a jeśli $varma wartość, oznacza to, że nie jest puste i zawsze zwróci prawdę.
JiNexus
89

Mam dzisiaj ten sam problem, rozwiązany w ten sposób:

Jeśli zadzwonisz json_decode($somestring), otrzymasz Obiekt i musisz uzyskać do niego dostęp $object->key, ale jeśli zadzwonisz json_decode($somestring, true), dostaniesz słownik i będziesz mógł uzyskać do niego dostęp$array['key']

Alexey Lysenko
źródło
2
Zaoszczędziło mi to tak dużo czasu! Nie wprowadzałem prawdziwego parametru i próbowałem uzyskać do niego dostęp jako tablicę
Meeyam
87

Użyj truejako drugiego parametru do json_decode. Spowoduje to dekodowanie pliku json w tablicy asocjacyjnej zamiast stdObjectinstancji:

$my_array = json_decode($my_json, true);

Więcej informacji znajduje się w dokumentacji .

Sander Marechal
źródło
61

To nie jest tablica, to obiekt typu stdClass.

Możesz uzyskać do niego dostęp w następujący sposób:

echo $oResult->context;

Więcej informacji tutaj: Co to jest stdClass w PHP?

Wesley van Opdorp
źródło
28

Jak mawiają Php Manual ,

print_r - Drukuje czytelne dla człowieka informacje o zmiennej

Kiedy używamy json_decode();, otrzymujemy obiekt typu stdClass jako typ zwracany. Argumenty, które mają być przekazane do wewnątrz, print_r()powinny być tablicą lub łańcuchem. Dlatego nie możemy przekazać obiektu do środka print_r(). Znalazłem 2 sposoby, aby sobie z tym poradzić.

  1. Rzuć obiekt na tablicę.
    Można to osiągnąć w następujący sposób.

    $a = (array)$object;
  2. Uzyskując dostęp do klucza obiektu
    Jak wspomniano wcześniej, podczas używania json_decode();funkcji zwraca obiekt stdClass. możesz uzyskać dostęp do elementów obiektu za pomocą ->operatora.

    $value = $object->key;

Jeden z nich może także używać wielu kluczy do wyodrębniania elementów podrzędnych, jeśli obiekt zagnieździł tablice.

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

Są też inne opcje print_r(), takie jak var_dump();ivar_export();

PS : Ponadto, jeśli ustawisz drugi parametr json_decode();na true, to automatycznie skonwertuje obiekt na array();
Oto kilka odnośników:
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

Panda
źródło
12

Aby uzyskać tablicę jako wynik ciągu json, powinieneś ustawić drugi parametr jako boolean true.

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

W przeciwnym razie wynikiem $ będzie obiekt standardowy. ale możesz uzyskać dostęp do wartości jako obiektu.

  $result = json_decode($json_string);
 $context = $result->context;
infomasud
źródło
8

Możesz przekonwertować obiekt stdClass na tablicę w następujący sposób:

$array = (array)$stdClass;

stdClsss do tablicy

Arnab
źródło
8

Kiedy próbujesz uzyskać do niego dostęp jako $result['context'], traktujesz go jako tablicę, błąd mówi ci, że faktycznie masz do czynienia z obiektem, to powinieneś uzyskać do niego dostęp jako$result->context

Midas Mtileni
źródło
4

Oto podpis funkcji:

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

Gdy param ma wartość false, co jest ustawieniem domyślnym, zwróci odpowiedni typ php. Możesz pobrać wartość tego typu za pomocą paradygmatu object.method.

Gdy param jest prawdziwy, zwróci tablice asocjacyjne.

W przypadku błędu zwróci NULL.

Jeśli chcesz pobrać wartość przez tablicę, ustaw assoc na true.

Robert
źródło
3

Czasami podczas pracy z API po prostu chcesz utrzymać obiekt jako obiekt. Aby uzyskać dostęp do obiektu, który ma zagnieżdżone obiekty, możesz wykonać następujące czynności:

Zakładamy, że po wydrukowaniu obiektu możesz zobaczyć to:

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
        )
)

Aby uzyskać dostęp do pierwszej części obiektu:

print $response->{'status'};

I to przyniosłoby „sukces”

Teraz kluczujemy pozostałe części:

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

Oczekiwany wynik to „Robert” z podziałem linii.

Możesz także ponownie przypisać część obiektu do innego obiektu.

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

Oczekiwany wynik to „Robert” z podziałem linii.

Aby uzyskać dostęp do następnego klawisza „1”, proces jest taki sam.

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

Oczekiwany wynik to „USA”

Mamy nadzieję, że pomoże ci to zrozumieć przedmioty i dlaczego chcemy zachować obiekt jako przedmiot. Aby uzyskać dostęp do jego właściwości, nie trzeba konwertować obiektu na tablicę.

Robert Saylor
źródło
2

zamiast używać nawiasów użyj operatora obiektu, na przykład twoja tablica oparta na obiekcie bazy danych jest tworzona w ten sposób w klasie o nazwie 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;
}

}

aby uzyskać dostęp do informacji używam tego kodu w skrypcie kontrolera:

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



?>

następnie, aby wyświetlić informacje, które sprawdzam, aby sprawdzić, czy wywołania serwisowe zostały ustawione i ma liczbę większą niż 0, pamiętaj, że nie jest to tablica, do której się odwołuję, więc uzyskuję dostęp do rekordów za pomocą operatora obiektu „->” w następujący sposób:

<?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'; ?>
timmac15
źródło
2

Ten błąd zniknął mi z oczu, ponieważ moje logowanie do Facebooka nagle przestało działać (zmieniłem również hosty) i zgłosiłem ten błąd. Poprawka jest naprawdę łatwa

Problem dotyczył tego kodu

  $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']);
  }

Zasadniczo funkcja isset () oczekuje tablicy, ale zamiast tego znajduje obiekt. Prostym rozwiązaniem jest konwersja obiektu PHP na tablicę za pomocą kwantyfikatora (tablicowego) . Poniżej przedstawiono poprawiony kod.

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

Zwróć uwagę na kwantyfikator use off array () w pierwszym wierszu.

Hammad Khan
źródło
1

Zmień to na

$results->fetch_array()
Dan Padilla
źródło