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); true를 추가하면 결과가 stdClass가 아닌 배열로 리턴됩니다.
Nepaluz

답변:


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
knockoutjs에 의해 설정된 PHP에서 _destroy 값을 참조하는 방법을 찾으려고 할 때 이것을 찾는 데 시간이 걸렸습니다. +1
deltree

2
이 답변은 첫 번째 (가장 평가 된) 답변보다 훨씬 더 자격이 있습니다!
Mojtaba Rezaeian

149

->객체이므로 이를 사용하여 액세스해야 합니다.

다음에서 코드를 변경하십시오.

$result['context'];

에:

$result->context;

내가 가진 문제는 조건부에서 속성을 사용하려고하는데 속성 if ($result->context = $var) 이 var로 설정되고 상관없이 true를 반환합니다.
STWilson

3
@STWilson 당신은 double equals를 사용해야 ==합니다. 현재 상태 에서는 single equal을 사용하여 $var값을 할당 합니다 . 그리고 는 비어 있거나없는 것처럼 읽으며 값이 있으면 비어 있지 않으며 항상 true를 반환합니다. $result->context=if statement$var
JiNexus

89

오늘 같은 문제가 다음과 같이 해결되었습니다.

당신이 전화 json_decode($somestring)하면 당신은 객체를 얻을 것이고 당신은 같은에 액세스해야 $object->key하지만, u 전화 json_decode($somestring, true)하면 당신은 사전을 얻고 다음과 같이 액세스 할 수 있습니다$array['key']


2
이것은 나에게 많은 시간을 구했다! 나는 진정한 매개 변수를 넣지 않고 배열로 액세스하려고했습니다
Meeyam

87

true의 두 번째 매개 변수로 사용하십시오 json_decode. 이것은 stdObject인스턴스 대신 json을 연관 배열로 디코딩합니다 .

$my_array = json_decode($my_json, true);

자세한 내용 은 설명서 를 참조하십시오.



28

Php 매뉴얼에서 말한 것처럼

print_r — 변수에 대한 사람이 읽을 수있는 정보를 인쇄합니다

를 사용할 때 json_decode();stdClass 유형의 객체를 반환 유형으로 얻습니다. 내부로 전달되는 인수 print_r()는 배열 또는 문자열이어야합니다. 따라서 내부에 객체를 전달할 수 없습니다 print_r(). 나는 이것을 다루는 두 가지 방법을 발견했다.

  1. 객체를 배열로 캐스트합니다.
    이것은 다음과 같이 달성 될 수 있습니다.

    $a = (array)$object;
  2. Object의 키에 액세스하여
    앞에서 언급했듯이 json_decode();함수 를 사용할 때 stdClass의 Object를 반환합니다. ->Operator 의 도움으로 객체의 요소에 액세스 할 수 있습니다 .

    $value = $object->key;

하나는 객체에 중첩 배열이있는 경우 여러 키를 사용하여 하위 요소를 추출 할 수도 있습니다.

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

그들의 다른 옵션은 print_r()물론, 같은 var_dump();var_export();

추신 : 당신이의 두 번째 매개 변수를 설정하는 경우 또한, 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'];

그렇지 않으면 $ result는 표준 개체가됩니다. 그러나 객체로 값에 액세스 할 수 있습니다.

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

param이 false 인 경우 (기본값) 적절한 PHP 유형을 반환합니다. object.method 패러다임을 사용하여 해당 유형의 값을 가져옵니다.

param이 true이면 연관 배열을 반환합니다.

오류가 발생하면 NULL을 반환합니다.

배열을 통해 값을 가져 오려면 assoc을 true로 설정하십시오.


3

때때로 API로 작업 할 때 단순히 객체를 객체로 유지하려고합니다. 중첩 된 객체가있는 객체에 액세스하려면 다음을 수행하십시오.

우리는 당신이 이것을 볼 수있는 객체를 print_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>";

줄 바꿈이있는 예상 출력은 "Robert"입니다.

객체의 일부를 다른 객체에 다시 할당 할 수도 있습니다.

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

줄 바꿈이있는 예상 출력은 "Robert"입니다.

다음 키 "1"에 액세스하려면 프로세스가 동일합니다.

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

예상 출력은 "USA"입니다.

바라건대 이것은 객체를 이해하고 객체를 객체로 유지하려는 이유를 이해하는 데 도움이되기를 바랍니다. 속성에 액세스하기 위해 객체를 배열로 변환하지 않아도됩니다.


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



?>

그런 다음 servicecalls가 설정되어 있고 카운트가 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

페이스 북 로그인이 갑자기 작동을 멈추고 (호스트도 변경 했음)이 오류가 발생했기 때문에이 오류가 파란색으로 표시되지 않았습니다. 수정은 정말 쉽습니다

이 코드에 문제가있었습니다

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

첫 번째 행에서 off array () 수량자를 사용하십시오.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.