¿No se puede usar el objeto de tipo stdClass como matriz?

541

Me sale un error extraño usando json_decode(). Decodifica correctamente los datos (lo vi usando print_r), pero cuando intento acceder a la información dentro de la matriz obtengo:

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

Solo intenté hacer: ¿ $result['context']dónde $resultha devuelto los datos?json_decode()

¿Cómo puedo leer valores dentro de esta matriz?

Dail
fuente
15
$ result = json_decode ('la cadena', verdadero); Agregar el verdadero devuelve el resultado como una matriz y no como una clase estándar.
Nepalí

Respuestas:

790

Use el segundo parámetro de json_decodepara que devuelva una matriz:

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

La función json_decode()devuelve un objeto por defecto.

Puede acceder a los datos de esta manera:

var_dump($result->context);

Si tiene identificadores como from-date(el guión podría causar un error de PHP al usar el método anterior) debe escribir:

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

Si desea una matriz, puede hacer algo como esto:

$result = json_decode($json, true);

O lanzar el objeto a una matriz:

$result = (array) json_decode($json);
svens
fuente
2
Me tomó un tiempo encontrar esto cuando trataba de encontrar una manera de referirme al valor _destroy en php que se establece mediante knockoutjs, por lo que +1
deltree
2
¡Esta respuesta es mucho más calificada que la primera (más valorada) respuesta!
Mojtaba Rezaeian
149

Debe acceder a él ->ya que es un objeto.

Cambia tu código de:

$result['context'];

A:

$result->context;
JiNexus
fuente
El problema que tengo es tratar de usar la propiedad de forma condicional. if ($result->context = $var) Esto hace que la propiedad se establezca en var y devuelve verdadero, no importa.
STWilson
3
@STWilson debería usar un doble igual ==, en su estado actual al que le está asignando $varvalor $result->contextusando un solo igual =. Y if statementlo leerá como si estuviera vacío o no, y si $vartiene valor, eso significa que no está vacío y siempre devolverá verdadero.
JiNexus
89

Tiene el mismo problema hoy, resuelto así:

Si llamas json_decode($somestring), obtendrás un Objeto y necesitas acceder como $object->key, pero si llamas json_decode($somestring, true)obtendrás un diccionario y podrás acceder como$array['key']

Alexey Lysenko
fuente
2
¡Esto me ahorró mucho tiempo! No estaba poniendo el parámetro verdadero e intentando acceder a él como una matriz
Meeyam
87

Use truecomo segundo parámetro para json_decode. Esto decodificará el json en una matriz asociativa en lugar de stdObjectinstancias:

$my_array = json_decode($my_json, true);

Consulte la documentación para más detalles.

Sander Marechal
fuente
61

No es una matriz, es un objeto de tipo stdClass.

Puedes acceder de esta manera:

echo $oResult->context;

Más información aquí: ¿Qué es stdClass en PHP?

Wesley van Opdorp
fuente
28

Como dice el Manual de Php ,

print_r - Imprime información legible por humanos sobre una variable

Cuando usamos json_decode();, obtenemos un objeto de tipo stdClass como tipo de retorno. Los argumentos, que se deben pasar dentro de, print_r()deben ser una matriz o una cadena. Por lo tanto, no podemos pasar un objeto dentro de print_r(). Encontré 2 formas de lidiar con esto.

  1. Lanza el objeto a la matriz.
    Esto se puede lograr de la siguiente manera.

    $a = (array)$object;
  2. Al acceder a la clave del Objeto
    Como se mencionó anteriormente, cuando usa la json_decode();función, devuelve un Objeto de stdClass. Puede acceder a los elementos del objeto con la ayuda del ->operador.

    $value = $object->key;

Uno, también puede usar varias claves para extraer los subelementos en caso de que el objeto tenga matrices anidadas.

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

print_r()También hay otras opciones para , como var_dump();yvar_export();

PD : Además, si configura el segundo parámetro de json_decode();to true, convertirá automáticamente el objeto en An. array();
Aquí hay algunas referencias:
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
fuente
12

Para obtener una matriz como resultado de una cadena json, debe establecer el segundo parámetro como verdadero booleano.

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

De lo contrario, $ result será un objeto estándar. pero puedes acceder a los valores como objeto.

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

Puede convertir el objeto stdClass en una matriz como:

$array = (array)$stdClass;

stdClsss a array

Arnab
fuente
8

Cuando intentas acceder a él como $result['context']si lo trataras como una matriz, el error te indica que en realidad estás tratando con un objeto, entonces debes acceder a él como$result->context

Midas Mtileni
fuente
4

Aquí está la firma de la función:

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

Cuando param es falso, que es el valor predeterminado, devolverá un tipo de php apropiado. Obtiene el valor de ese tipo utilizando el paradigma object.method.

Cuando param es verdadero, devolverá matrices asociativas.

Devolverá NULL en caso de error.

Si desea obtener valor a través de la matriz, establezca assoc en true.

robert
fuente
3

A veces, cuando se trabaja con API, simplemente desea mantener un objeto en un objeto. Para acceder al objeto que tiene objetos anidados, puede hacer lo siguiente:

Asumiremos que cuando imprime_r el objeto puede ver esto:

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

Para acceder a la primera parte del objeto:

print $response->{'status'};

Y eso generaría "éxito"

Ahora tecleemos las otras partes:

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

El resultado esperado sería "Robert" con un salto de línea.

También puede reasignar parte del objeto a otro objeto.

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

El resultado esperado sería "Robert" con un salto de línea.

Para acceder a la siguiente clave "1", el proceso es el mismo.

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

El resultado esperado sería "EE. UU."

Esperemos que esto lo ayude a comprender los objetos y por qué queremos mantener un objeto en un objeto. No debería necesitar convertir un objeto en una matriz para acceder a sus propiedades.

Robert Saylor
fuente
2

en lugar de usar los corchetes, use el operador de objeto, por ejemplo, mi matriz basada en un objeto de base de datos se crea así en una clase llamada 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;
}

}

para acceder a la información uso este código en el script del controlador:

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



?>

luego para mostrar la información que verifico para ver si las llamadas de servicio se han configurado y tienen un recuento mayor que 0 recuerde que no es una matriz a la que me refiero, así que accedo a los registros con el operador de objeto "->" de esta manera:

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

Obtuve este error de la nada porque mi inicio de sesión de Facebook dejó de funcionar repentinamente (también había cambiado de host) y arrojé este error. La solución es realmente fácil.

El problema estaba en este código

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

Básicamente, la función isset () espera una matriz pero en su lugar encuentra un objeto. La solución simple es convertir un objeto PHP a una matriz usando el cuantificador (matriz) . El siguiente es el código fijo.

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

Tenga en cuenta el uso del cuantificador off array () en la primera línea.

Hammad Khan
fuente
1

Cámbialo por

$results->fetch_array()
Dan Padilla
fuente