Objekt vom Typ stdClass kann nicht als Array verwendet werden?


541

Ich bekomme einen seltsamen Fehler mit json_decode(). Es dekodiert die Daten korrekt (ich habe es mit gesehen print_r), aber wenn ich versuche, auf Informationen innerhalb des Arrays zuzugreifen, erhalte ich:

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

Ich habe versucht , nur das zu tun: $result['context']wo $resultdie Daten hat wieder durchjson_decode()

Wie kann ich Werte in diesem Array lesen?


15
$ result = json_decode ('der String', true); Durch Hinzufügen von true wird das Ergebnis als Array und nicht als stdClass zurückgegeben.
Nepaluz

Antworten:


789

Verwenden Sie den zweiten Parameter von json_decode, um ein Array zurückzugeben:

$result = json_decode($data, true);

209

Die Funktion json_decode()gibt standardmäßig ein Objekt zurück.

Sie können auf die Daten folgendermaßen zugreifen:

var_dump($result->context);

Wenn Sie Bezeichner wie haben from-date(der Bindestrich würde bei Verwendung der obigen Methode einen PHP-Fehler verursachen), müssen Sie schreiben:

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

Wenn Sie ein Array möchten, können Sie Folgendes tun:

$result = json_decode($json, true);

Oder wandeln Sie das Objekt in ein Array um:

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

2
Ich habe eine Weile gebraucht, um dies zu finden, als ich versucht habe, einen Weg zu finden, um auf den _destroy-Wert in PHP zu verweisen, der von knockoutjs festgelegt wurde, also +1
deltree

2
Diese Antwort ist viel qualifizierter als die erste (am meisten bewertete) Antwort!
Mojtaba Rezaeian

149

Sie müssen mit darauf zugreifen, ->da es sich um ein Objekt handelt.

Ändern Sie Ihren Code von:

$result['context'];

Zu:

$result->context;

Das Problem, das ich habe, ist der Versuch, die Eigenschaft in einer Bedingung zu verwenden. if ($result->context = $var) Dies führt dazu, dass die Eigenschaft auf var gesetzt wird und true zurückgibt, unabhängig davon.
STWilson

3
@STWilson Sie sollten ein Double Equals verwenden ==. In Ihrem aktuellen Status weisen Sie einen $varWert zu, $result->contextindem Sie ein Single Equal verwenden =. Und der if statementwird es lesen, als ob es leer ist oder nicht, und wenn das $vareinen Wert hat, bedeutet das, dass es nicht leer ist und immer true zurückgibt.
JiNexus

89

Habe heute das gleiche Problem, so gelöst:

Wenn Sie rufen json_decode($somestring)Sie ein Objekt erhalten wird , und Sie müssen Zugang wie $object->key, aber wenn u nennen json_decode($somestring, true)werden Sie ein Wörterbuch und können den Zugriff bekommen$array['key']


2
Das hat mir sooo viel Zeit gespart! Ich habe den wahren Parameter nicht
eingegeben

87

Verwenden Sie trueals zweiten Parameter zu json_decode. Dadurch wird der JSON in ein assoziatives Array anstelle von stdObjectInstanzen dekodiert :

$my_array = json_decode($my_json, true);

Weitere Informationen finden Sie in der Dokumentation .



28

Wie das PHP-Handbuch sagt,

print_r - Druckt lesbare Informationen zu einer Variablen

Wenn wir verwenden json_decode();, erhalten wir ein Objekt vom Typ stdClass als Rückgabetyp. Die Argumente, die innerhalb von übergeben werden print_r()sollen, sollten entweder ein Array oder eine Zeichenfolge sein. Daher können wir kein Objekt innerhalb von übergeben print_r(). Ich habe zwei Möglichkeiten gefunden, damit umzugehen.

  1. Wandeln Sie das Objekt in ein Array um.
    Dies kann wie folgt erreicht werden.

    $a = (array)$object;
  2. Durch Zugriff auf den Schlüssel des Objekts
    Wie bereits erwähnt, wird bei Verwendung der json_decode();Funktion ein Objekt von stdClass zurückgegeben. Sie können mit Hilfe von ->Operator auf die Elemente des Objekts zugreifen .

    $value = $object->key;

Zum einen können auch mehrere Schlüssel verwendet werden, um die Unterelemente zu extrahieren, falls das Objekt verschachtelte Arrays hat.

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

Es gibt auch andere Möglichkeiten print_r(), wie var_dump();undvar_export();

PS : Wenn Sie den zweiten Parameter von json_decode();to festlegen true, wird das Objekt automatisch in ein konvertiert. array();
Hier einige Referenzen:
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

Um ein Array als Ergebnis einer JSON-Zeichenfolge zu erhalten, sollten Sie den zweiten Parameter als boolean true festlegen.

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

Andernfalls ist $ result ein Standardobjekt. Sie können jedoch als Objekt auf Werte zugreifen.

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


8

Wenn Sie versuchen, darauf zuzugreifen $result['context'], behandeln Sie es als Array. Der Fehler, der Ihnen sagt, dass Sie sich tatsächlich mit einem Objekt befassen, dann sollten Sie darauf zugreifen als$result->context


4

Hier ist die Funktionssignatur:

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

Wenn param false ist (Standardeinstellung), wird ein geeigneter PHP-Typ zurückgegeben. Sie rufen den Wert dieses Typs mithilfe des object.method-Paradigmas ab.

Wenn param wahr ist, werden assoziative Arrays zurückgegeben.

Bei einem Fehler wird NULL zurückgegeben.

Wenn Sie einen Wert über das Array abrufen möchten, setzen Sie assoc auf true.


3

Manchmal möchten Sie bei der Arbeit mit API einfach ein Objekt als Objekt behalten. Um auf das Objekt mit verschachtelten Objekten zuzugreifen, haben Sie folgende Möglichkeiten:

Wir gehen davon aus, dass beim Drucken des Objekts Folgendes angezeigt wird:

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

So greifen Sie auf den ersten Teil des Objekts zu:

print $response->{'status'};

Und das würde "Erfolg" ausgeben

Lassen Sie uns nun die anderen Teile eingeben:

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

Die erwartete Ausgabe wäre "Robert" mit einem Zeilenumbruch.

Sie können einen Teil des Objekts auch einem anderen Objekt zuweisen.

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

Die erwartete Ausgabe wäre "Robert" mit einem Zeilenumbruch.

Um auf die nächste Taste "1" zuzugreifen, ist der Vorgang der gleiche.

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

Die erwartete Ausgabe wäre "USA"

Hoffentlich hilft Ihnen dies dabei, Objekte zu verstehen und warum wir ein Objekt als Objekt behalten möchten. Sie sollten ein Objekt nicht in ein Array konvertieren müssen, um auf seine Eigenschaften zuzugreifen.


2

Anstatt die Klammern zu verwenden, verwenden Sie beispielsweise den Objektoperator. Mein auf einem Datenbankobjekt basierendes Array wird in einer Klasse namens DB folgendermaßen erstellt:

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

}

Um auf die Informationen zuzugreifen, verwende ich diesen Code im Controller-Skript:

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



?>

Um dann die Informationen anzuzeigen, überprüfe ich, ob Servicecalls festgelegt wurden und eine Anzahl größer als 0 hat. Denken Sie daran, dass es sich nicht um ein Array handelt, auf das ich verweise. Daher greife ich mit dem Objektoperator "->" wie folgt auf die Datensätze zu:

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

Ich habe diesen Fehler aus heiterem Himmel erhalten, weil mein Facebook-Login plötzlich nicht mehr funktioniert (ich hatte auch die Hosts gewechselt) und diesen Fehler ausgelöst hat. Das Update ist wirklich einfach

Das Problem war in diesem Code

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

Grundsätzlich erwartet die Funktion isset () ein Array, findet aber stattdessen ein Objekt. Die einfache Lösung besteht darin, ein PHP-Objekt mithilfe eines (Array-) Quantifizierers in ein Array zu konvertieren . Das Folgende ist der feste Code.

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

Beachten Sie den Quantifizierer use off array () in der ersten Zeile.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.