Không thể sử dụng đối tượng của kiểu stdClass làm mảng?


541

Tôi nhận được một lỗi lạ khi sử dụng json_decode(). Nó giải mã chính xác dữ liệu (tôi đã thấy nó sử dụng print_r), nhưng khi tôi cố gắng truy cập vào thông tin bên trong mảng tôi nhận được:

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

Tôi chỉ cố gắng làm: $result['context']nơi $resultcó dữ liệu được trả vềjson_decode()

Làm thế nào tôi có thể đọc các giá trị trong mảng này?


15
$ result = json_decode ('chuỗi', đúng); Thêm true trả về kết quả dưới dạng một mảng chứ không phải stdClass.
Nepaluz

Câu trả lời:


789

Sử dụng tham số thứ hai của json_decodeđể làm cho nó trả về một mảng:

$result = json_decode($data, true);

209

Hàm json_decode()trả về một đối tượng theo mặc định.

Bạn có thể truy cập dữ liệu như thế này:

var_dump($result->context);

Nếu bạn có số nhận dạng như from-date(dấu gạch nối sẽ gây ra lỗi PHP khi sử dụng phương pháp trên), bạn phải viết:

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

Nếu bạn muốn một mảng, bạn có thể làm một cái gì đó như thế này:

$result = json_decode($json, true);

Hoặc truyền đối tượng vào một mảng:

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

2
tôi đã mất một lúc để tìm thấy điều này khi cố gắng tìm cách tham khảo giá trị _destroy trong php được đặt bởi knoutoutjs, vì vậy +1
deltree

2
Câu trả lời này đủ điều kiện hơn nhiều so với câu trả lời đầu tiên (được đánh giá cao nhất)!
Mojtaba Rezaeian

149

Bạn phải truy cập nó bằng cách sử dụng nó ->từ một đối tượng.

Thay đổi mã của bạn từ:

$result['context'];

Đến:

$result->context;

Vấn đề tôi gặp phải là cố gắng sử dụng thuộc tính trong điều kiện if ($result->context = $var) Điều này làm cho thuộc tính được đặt thành var và trả về true, bất kể là gì.
STWilson

3
@STWilson bạn nên sử dụng một số bằng ==, trong trạng thái hiện tại của bạn, bạn đang gán $vargiá trị cho $result->contextbằng cách sử dụng một bằng một =. Và ý if statementchí sẽ đọc nó như thể nó trống hay không, và nếu $varcó giá trị thì điều đó có nghĩa là nó không trống và sẽ luôn trả về đúng.
JiNexus

89

Có vấn đề tương tự ngày hôm nay, giải quyết như thế này:

Nếu bạn gọi, json_decode($somestring)bạn sẽ nhận được một Đối tượng và bạn cần truy cập như thế $object->key, nhưng nếu bạn gọi, json_decode($somestring, true)bạn sẽ nhận được một từ điển và có thể truy cập như$array['key']


2
Điều này giúp tôi tiết kiệm rất nhiều thời gian! Tôi đã không đưa vào tham số thực sự và cố gắng truy cập nó dưới dạng một mảng
Meeyam 7/12/18

87

Sử dụng truelàm tham số thứ hai để json_decode. Điều này sẽ giải mã json thành một mảng kết hợp thay vì các stdObjectthể hiện:

$my_array = json_decode($my_json, true);

Xem tài liệu để biết thêm chi tiết.



28

Như Hướng dẫn Php nói,

print_r - In thông tin có thể đọc được của con người về một biến

Khi chúng ta sử dụng json_decode();, chúng ta sẽ nhận được một đối tượng kiểu stdClass là kiểu trả về. Các đối số được truyền vào bên trong print_r()phải là một mảng hoặc một chuỗi. Do đó, chúng ta không thể vượt qua một đối tượng bên trong print_r(). Tôi tìm thấy 2 cách để đối phó với điều này.

  1. Truyền đối tượng vào mảng.
    Điều này có thể đạt được như sau.

    $a = (array)$object;
  2. Bằng cách truy cập khóa của Object
    Như đã đề cập trước đó, khi bạn sử dụng json_decode();hàm, nó sẽ trả về Object của stdClass. bạn có thể truy cập các phần tử của đối tượng với sự trợ giúp của ->Toán tử.

    $value = $object->key;

Một, cũng có thể sử dụng nhiều khóa để trích xuất các phần tử phụ nếu đối tượng có các mảng lồng nhau.

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

Họ là những lựa chọn khác để print_r(), như var_dump();var_export();

PS : Ngoài ra, nếu bạn đặt tham số thứ hai của json_decode();thành true, nó sẽ tự động chuyển đổi đối tượng thành array();
Dưới đây là một số tài liệu tham khảo:
http://php.net/manual/en/feft.print-r.php
http: // php.net/manual/en/feft.var-dump.php
http://php.net/manual/en/feft.var-export.php


12

Để có được một mảng là kết quả từ một chuỗi json, bạn nên đặt param thứ hai là boolean true.

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

Nếu không, kết quả $ sẽ là một đối tượng tiêu chuẩn. nhưng bạn có thể truy cập các giá trị như đối tượng.

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


8

Khi bạn cố gắng truy cập nó dưới dạng $result['context'], bạn coi nó như một mảng, lỗi sẽ cho bạn biết rằng bạn đang thực sự xử lý một đối tượng, sau đó bạn nên truy cập nó như là một$result->context


4

Đây là chữ ký hàm:

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

Khi param là false, là mặc định, nó sẽ trả về một loại php thích hợp. Bạn lấy giá trị của loại đó bằng mô hình object.method.

Khi param là true, nó sẽ trả về mảng kết hợp.

Nó sẽ trả về NULL khi có lỗi.

Nếu bạn muốn tìm nạp giá trị qua mảng, đặt PGS thành true.


3

Đôi khi khi làm việc với API, bạn chỉ muốn giữ một đối tượng là một đối tượng. Để truy cập đối tượng có các đối tượng lồng nhau, bạn có thể làm như sau:

Chúng tôi sẽ giả sử khi bạn print_r đối tượng bạn có thể thấy điều này:

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

Để truy cập phần đầu tiên của đối tượng:

print $response->{'status'};

Và điều đó sẽ tạo ra "thành công"

Bây giờ hãy để các phần khác:

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

Sản lượng dự kiến ​​sẽ là "Robert" với ngắt dòng.

Bạn cũng có thể gán lại một phần của đối tượng cho đối tượng khác.

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

Sản lượng dự kiến ​​sẽ là "Robert" với ngắt dòng.

Để truy cập khóa tiếp theo "1", quy trình là như nhau.

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

Sản lượng dự kiến ​​sẽ là "USA"

Hy vọng rằng điều này sẽ giúp bạn hiểu các đối tượng và lý do tại sao chúng tôi muốn giữ một đối tượng một đối tượng. Bạn không cần phải chuyển đổi một đối tượng thành một mảng để truy cập các thuộc tính của nó.


2

thay vì sử dụng dấu ngoặc, sử dụng toán tử đối tượng, ví dụ mảng của tôi dựa trên đối tượng cơ sở dữ liệu được tạo như thế này trong một lớp có tên 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;
}

}

để truy cập thông tin tôi sử dụng mã này trên tập lệnh của bộ điều khiển:

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



?>

sau đó để hiển thị thông tin tôi kiểm tra xem liệu dịch vụ đã được thiết lập chưa và có số đếm lớn hơn 0 không phải là mảng tôi đang tham chiếu nên tôi truy cập vào các bản ghi với toán tử đối tượng "->" như thế này:

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

Tôi đã nhận được lỗi này do lỗi đăng nhập facebook của tôi đột nhiên ngừng hoạt động (tôi cũng đã thay đổi máy chủ) và ném lỗi này. Cách khắc phục rất dễ

Vấn đề là ở mã này

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

Về cơ bản, hàm hàmetet () mong đợi một mảng nhưng thay vào đó, nó tìm thấy một đối tượng. Giải pháp đơn giản là chuyển đổi đối tượng PHP thành mảng bằng cách sử dụng bộ định lượng (mảng) . Sau đây là mã cố định.

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

Lưu ý sử dụng bộ định lượng mảng off () trong dòng đầu tiên.


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.