ไม่สามารถใช้วัตถุประเภท 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']ที่ไหน$resultjson_decode()

ฉันจะอ่านค่าภายในอาร์เรย์นี้ได้อย่างไร


15
$ result = json_decode ('สตริง', จริง); การเพิ่ม true ส่งคืนผลลัพธ์เป็นอาร์เรย์ไม่ใช่ stdClass
Nepaluz

คำตอบ:



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
คำตอบนี้เป็นมากขึ้นกว่าที่ผ่านการรับรองครั้งแรก (จัดอันดับมากที่สุด) คำตอบ!
Mojtaba Rezaeian

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->keyแต่ถ้าคุณโทรjson_decode($somestring, true)คุณจะได้รับพจนานุกรมและสามารถเข้าถึงได้เช่นกัน$array['key']


2
สิ่งนี้ช่วยฉันได้มากเวลา! ฉันไม่ได้ใส่พารามิเตอร์จริงและพยายามที่จะเข้าถึงมันเป็นอาร์เรย์
Meeyam

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 ของ stdClass คุณสามารถเข้าถึงองค์ประกอบของวัตถุได้โดยใช้->Operator

    $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 คุณควรตั้งค่าพารามิเตอร์ที่สองเป็นบูลีนจริง

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

มิฉะนั้นผลลัพธ์ $ จะเป็นวัตถุมาตรฐาน แต่คุณสามารถเข้าถึงค่าเป็นวัตถุ

  $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 เป็นจริง


3

บางครั้งเมื่อทำงานกับ API คุณเพียงต้องการเก็บวัตถุเป็นวัตถุ ในการเข้าถึงวัตถุที่มีวัตถุซ้อนอยู่คุณสามารถทำสิ่งต่อไปนี้:

เราจะถือว่าเมื่อคุณพิมพ์วัตถุคุณอาจเห็นสิ่งนี้:

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

ผลลัพธ์ที่คาดหวังจะเป็น "สหรัฐอเมริกา"

หวังว่านี่จะช่วยให้คุณเข้าใจวัตถุและทำไมเราต้องการเก็บวัตถุเป็นวัตถุ คุณไม่จำเป็นต้องแปลงวัตถุเป็นอาร์เรย์เพื่อเข้าถึงคุณสมบัติ


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



?>

จากนั้นเพื่อแสดงข้อมูลที่ฉันตรวจสอบเพื่อดูว่ามีการตั้งค่า servicecs และมีจำนวนมากกว่า 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 ล็อกอินของฉัน suddently หยุดทำงาน (ฉันยังมีการเปลี่ยนแปลงเป็นเจ้าภาพ) และเหวี่ยงข้อผิดพลาดนี้ การแก้ไขนั้นง่ายมาก

ปัญหานี้อยู่ในรหัสนี้

  $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.