Impossible d'utiliser un objet de type stdClass comme tableau?

541

J'obtiens une erreur étrange en utilisant json_decode(). Il décode correctement les données (je les ai vues utiliser print_r), mais lorsque j'essaie d'accéder aux informations à l'intérieur du tableau, j'obtiens:

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

J'ai seulement essayé de faire: $result['context']$resultles données sont-elles retournées parjson_decode()

Comment puis-je lire des valeurs à l'intérieur de ce tableau?

Dail
la source
15
$ result = json_decode ('la chaîne', true); L'ajout de true renvoie le résultat sous forme de tableau et non de stdClass.
Nepaluz

Réponses:

790

Utilisez le second paramètre de json_decodepour lui faire retourner un tableau:

$result = json_decode($data, true);
Jon
la source
209

La fonction json_decode()renvoie un objet par défaut.

Vous pouvez accéder aux données comme ceci:

var_dump($result->context);

Si vous avez des identifiants comme from-date(le trait d'union provoquerait une erreur PHP lors de l'utilisation de la méthode ci-dessus), vous devez écrire:

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

Si vous voulez un tableau, vous pouvez faire quelque chose comme ceci:

$result = json_decode($json, true);

Ou convertissez l'objet en tableau:

$result = (array) json_decode($json);
svens
la source
2
Il m'a fallu un certain temps pour trouver cela lorsque j'essayais de trouver un moyen de faire référence à la valeur _destroy en php définie par knockoutjs, donc +1
deltree
2
Cette réponse est beaucoup plus qualifiée que la première réponse (la plus appréciée)!
Mojtaba Rezaeian
149

Vous devez y accéder en utilisant ->depuis son un objet.

Changez votre code de:

$result['context'];

À:

$result->context;
JiNexus
la source
Le problème que j'ai est d'essayer d'utiliser la propriété dans un conditionnel if ($result->context = $var) Cela provoque la propriété d'être définie sur la var et renvoie true, peu importe.
STWilson
3
@STWilson, vous devez utiliser un double égal ==, dans votre état actuel, vous attribuez une $varvaleur $result->contexten utilisant un seul égal =. Et le if statementlira comme s'il était vide ou non, et si la $varvaleur a alors cela signifie qu'il n'est pas vide et retournera toujours vrai.
JiNexus
89

J'ai le même problème aujourd'hui, résolu comme ceci:

Si vous appelez, json_decode($somestring)vous obtiendrez un objet et vous devrez accéder à like $object->key, mais si vous appelez, json_decode($somestring, true)vous obtiendrez un dictionnaire et pourrez accéder à like$array['key']

Alexey Lysenko
la source
2
Cela m'a fait gagner tellement de temps! Je ne mettais pas le vrai paramètre et j'essayais d'y accéder en tant que tableau
Meeyam
87

Utiliser truecomme deuxième paramètre pour json_decode. Cela décodera le json en un tableau associatif au lieu d' stdObjectinstances:

$my_array = json_decode($my_json, true);

Voir la documentation pour plus de détails.

Sander Marechal
la source
61

Ce n'est pas un tableau, c'est un objet de type stdClass.

Vous pouvez y accéder comme ceci:

echo $oResult->context;

Plus d'informations ici: Qu'est-ce que stdClass en PHP?

Wesley van Opdorp
la source
28

Comme le dit le manuel Php ,

print_r - Imprime des informations lisibles par l'homme sur une variable

Lorsque nous utilisons json_decode();, nous obtenons un objet de type stdClass comme type de retour. Les arguments qui doivent être passés à l'intérieur de print_r()doivent être soit un tableau soit une chaîne. Par conséquent, nous ne pouvons pas passer un objet à l'intérieur de print_r(). J'ai trouvé 2 façons de gérer cela.

  1. Convertissez l'objet en tableau.
    Ceci peut être réalisé comme suit.

    $a = (array)$object;
  2. En accédant à la clé de l'objet
    Comme mentionné précédemment, lorsque vous utilisez la json_decode();fonction, elle renvoie un objet de stdClass. vous pouvez accéder aux éléments de l'objet à l'aide de-> opérateur.

    $value = $object->key;

Un, peut également utiliser plusieurs clés pour extraire les sous-éléments au cas où l'objet aurait des tableaux imbriqués.

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

Ce sont d'autres options pour print_r() , comme var_dump();etvar_export();

PS : Aussi, si vous définissez le deuxième paramètre de l' json_decode();à true, il convertit automatiquement l'objet d'une array();
Voici quelques références:
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
la source
12

Pour obtenir un tableau à la suite d'une chaîne json, vous devez définir le deuxième paramètre comme booléen true.

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

Sinon, $ result sera un objet std. mais vous pouvez accéder aux valeurs en tant qu'objet.

  $result = json_decode($json_string);
 $context = $result->context;
infomasud
la source
8

Lorsque vous essayez d'y accéder en tant que $result['context'], vous le traitez comme un tableau, l'erreur vous indique que vous avez réellement affaire à un objet, alors vous devez y accéder en tant que$result->context

Midas Mtileni
la source
4

Voici la signature de la fonction:

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

Lorsque param est faux, ce qui est par défaut, il retournera un type de php approprié. Vous récupérez la valeur de ce type à l'aide du paradigme object.method.

Lorsque param est vrai, il retournera des tableaux associatifs.

Il renverra NULL en cas d'erreur.

Si vous souhaitez récupérer la valeur via le tableau, définissez assoc sur true.

robert
la source
3

Parfois, lorsque vous travaillez avec l'API, vous souhaitez simplement conserver un objet un objet. Pour accéder à l'objet contenant des objets imbriqués, vous pouvez procéder comme suit:

Nous supposerons que lorsque vous imprimez l'objet, vous pouvez voir ceci:

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

Pour accéder à la première partie de l'objet:

print $response->{'status'};

Et cela donnerait un "succès"

Maintenant, saisissons les autres parties:

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

La sortie attendue serait "Robert" avec un saut de ligne.

Vous pouvez également réaffecter une partie de l'objet à un autre objet.

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

La sortie attendue serait "Robert" avec un saut de ligne.

Pour accéder à la touche "1" suivante, le processus est le même.

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

La sortie attendue serait "USA"

J'espère que cela vous aidera à comprendre les objets et pourquoi nous voulons garder un objet un objet. Vous ne devriez pas avoir besoin de convertir un objet en tableau pour accéder à ses propriétés.

Robert Saylor
la source
2

au lieu d'utiliser les crochets, utilisez l'opérateur objet, par exemple, mon tableau basé sur l'objet de base de données est créé comme ceci dans une classe appelée 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;
}

}

pour accéder aux informations j'utilise ce code sur le script du contrôleur:

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



?>

puis pour afficher les informations que je vérifie pour voir si les appels de service ont été définis et ont un nombre supérieur à 0, rappelez-vous que ce n'est pas un tableau auquel je fais référence, donc j'accède aux enregistrements avec l'opérateur d'objet "->" comme ceci:

<?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
la source
2

J'ai obtenu cette erreur à l'improviste parce que ma connexion Facebook a soudainement cessé de fonctionner (j'avais également changé d'hôtes) et jeté cette erreur. La solution est vraiment facile

Le problème était dans ce 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']);
  }

Fondamentalement, la fonction isset () attend un tableau mais à la place elle trouve un objet. La solution simple consiste à convertir un objet PHP en tableau à l'aide d'un quantificateur (array) . Voici le code fixe.

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

Notez le quantificateur use off array () en première ligne.

Hammad Khan
la source
1

Changez-le pour

$results->fetch_array()
Dan Padilla
la source