Не можете використовувати об’єкт типу stdClass як масив?


541

Я отримую дивну помилку за допомогою 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()

Як я можу прочитати значення всередині цього масиву?


15
$ result = json_decode ('рядок', правда); Додавання true повертає результат у вигляді масиву, а не stdClass.
Непалуз

Відповіді:


789

Використовуйте другий параметр, json_decodeщоб повернути масив:

$result = json_decode($data, true);

209

Функція 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
deltree

2
Ця відповідь набагато кваліфікованіша, ніж перша (найбільш оцінені) відповідь!
Мойтаба Резайан

149

Ви повинні отримати доступ до нього, використовуючи ->його об'єкт.

Змініть свій код з:

$result['context'];

До:

$result->context;

Проблема, яку я маю, намагається використовувати властивість умовно. if ($result->context = $var) Це призводить до того, що властивість буде встановлено на var і поверне справжнє значення, незалежно від того.
STWilson

3
@STWilson вам слід використовувати подвійне рівне ==, у поточному стані ви присвоюєте $varзначення $result->context, використовуючи одинакове рівне =. І if statementволя прочитає це так, ніби він порожній чи ні, і якщо $varзначення має значення, то це означає, що воно не порожнє і завжди повернеться істинним.
JiNexus

89

Маємо таку ж проблему сьогодні, вирішувану так:

Якщо ви зателефонуєте, json_decode($somestring)ви отримаєте Object, і вам потрібно мати доступ, як $object->key, але якщо ви дзвоните, json_decode($somestring, true)ви отримаєте словник і зможете отримати доступ до$array['key']


2
Це врятувало мені так багато часу! Я не
вводив

87

Використовувати trueяк другий параметр для json_decode. Це декодує json в асоціативний масив замість stdObjectекземплярів:

$my_array = json_decode($my_json, true);

Детальнішу інформацію див. У документації .



28

Як говорить посібник Php ,

print_r - друкує інформацію, що читається людиною, про змінну

Під час використання json_decode();ми отримуємо об’єкт типу stdClass як тип повернення. Аргументи, які мають бути передані всередині, print_r()повинні бути або масивом, або рядком. Отже, ми не можемо передати об’єкт всередині print_r(). Я знайшов 2 способи впоратися з цим.

  1. Відкинь об’єкт до масиву.
    Цього можна досягти наступним чином.

    $a = (array)$object;
  2. Доступ до ключа Object
    Як було сказано раніше, коли ви використовуєте json_decode();функцію, він повертає Object of stdClass. Ви можете отримати доступ до елементів об’єкта за допомогою ->Оператора.

    $value = $object->key;

Один, можна також використовувати декілька клавіш для вилучення суб-елементів у корпус, якщо об’єкт вклав масиви.

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

Вони також інші варіанти, print_r()як, як var_dump();іvar_export();

PS : Якщо ви встановите другий параметр 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


12

Щоб отримати масив в результаті рядка json, слід встановити другий параметр як булевий true.

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

Інакше $ результат стане об'єктом std. але ви можете отримати доступ до значень як об'єкт.

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


8

Коли ви намагаєтесь отримати доступ до нього як $result['context'], ви трактуєте його як масив, помилка, яка говорить вам про те, що ви насправді маєте справу з об'єктом, тоді вам слід отримати доступ до нього як$result->context


4

Ось функція підпису:

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

Якщо парам є неправдивим, за замовчуванням він поверне відповідний тип php. Значення цього типу ви отримуєте за допомогою парадигми object.method.

Коли парам відповідає дійсності, він повертає асоціативні масиви.

Він поверне NULL за помилку.

Якщо ви хочете отримати значення через масив, встановіть Assoc на true.


3

Іноді під час роботи з API просто хочеться зберегти об'єкт об'єктом. Для доступу до об'єкта, який вклав об'єкти, ви можете зробити наступне:

Ми будемо вважати, що коли ви друкуєте_r об'єкт, ви можете бачити це:

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

Для доступу до першої частини об’єкта:

print $response->{'status'};

І це призведе до "успіху"

Тепер давайте вкажемо інші частини:

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

Очікуваний вихід буде "Роберт" з розривом лінії.

Ви також можете призначити частину об'єкта іншому об'єкту.

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

Очікуваний вихід буде "Роберт" з розривом лінії.

Для доступу до наступної клавіші "1" процес той самий.

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

Очікуваний вихід буде "США"

Сподіваємось, це допоможе вам зрозуміти об’єкти і чому ми хочемо зберегти об’єкт. Вам не потрібно перетворювати об’єкт у масив, щоб отримати доступ до його властивостей.


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

}

для доступу до інформації, якою я користуюсь цим кодом у сценарії контролера:

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



?>

потім для відображення інформації, яку я перевіряю, чи встановлено виклик послуг і чисельність перевищує 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="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

Цю помилку я зрозумів, бо мій логін у 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 () у першому рядку.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.