不能使用类型为stdClass的对象作为数组?

我得到一个奇怪的错误使用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()返回的数据

如何读取这个数组中的值?

933122 次浏览

它不是数组,而是stdClass类型的对象。

你可以像这样访问它:

echo $oResult->context;

更多信息在这里:什么是PHP中的stdClass ?

使用true作为json_decode的第二个参数。这将把json解码成一个关联数组,而不是stdObject实例:

$my_array = json_decode($my_json, true);

更多细节请参见的文档

使用json_decode的第二个参数使它返回一个数组:

$result = json_decode($data, true);

函数json_decode()默认返回一个对象。

你可以像这样访问数据:

var_dump($result->context);

如果你有像from-date这样的标识符(使用上面的方法时,连字符会导致PHP错误),你必须写:

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

如果你想要一个数组,你可以这样做:

$result = json_decode($json, true);

或者将对象转换为数组:

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

不要使用括号,而是使用对象操作符,例如,我的基于数据库对象的数组是在一个名为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="/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'; ?>

你必须使用->来访问它,因为它是一个对象。

更改您的代码:

$result['context'];

:

$result->context;

你可以像这样将stdClass对象转换为数组:

$array = (array)$stdClass;

stdclassss to array

下面是函数签名:

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

当param为false(默认值)时,它将返回适当的php类型。您可以使用object获取该类型的值。方法范式。

当param为true时,它将返回关联数组。

它将在错误时返回NULL。

如果你想通过数组获取值,将assoc设置为true。

今天遇到同样的问题,是这样解决的:

如果你调用json_decode($somestring),你会得到一个对象,你需要访问像$object->key,但如果你调用json_decode($somestring, true),你会得到一个字典,可以访问像$array['key']

正如Php手册所说,

print_r -打印关于变量
的人类可读信息

当我们使用json_decode();时,我们得到一个类型为stdClass的对象作为返回类型。 要在print_r()中传递的参数应该是数组或字符串。因此,我们不能在print_r()中传递对象。我找到了两种处理方法。< / p >
    <李> < p > # EYZ0 < br >

    $a = (array)$object;
    
  1. By accessing the key of the Object
    As mentioned earlier, when you use json_decode(); function, it returns an Object of stdClass. you can access the elements of the object with the help of -> Operator.

    $value = $object->key;
    

One, can also use multiple keys to extract the sub elements incase if the object has nested arrays.

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

除了print_r(),还有其他选项,比如var_dump();var_export();

附::同样,如果你将json_decode();的第二个参数设置为true,它将自动将对象转换为array();
# EYZ0 < br > # EYZ0 < br > # EYZ0 < br > # EYZ0 < / p >

当你试图访问它作为$result['context'],你把它作为一个数组,错误它告诉你,你实际上是在处理一个对象,那么你应该访问它作为$result->context

改成

$results->fetch_array()

我突然得到了这个错误,因为我的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);

注意在第一行中使用了off array()量词。

为了从json字符串中得到一个数组,你应该将第二个参数设置为boolean true。

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

否则$result将是一个std对象。但是您可以以对象的形式访问值。

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

有时候在使用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'};

这将输出"success"

现在让我们调整其他部分:

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

预期输出将是“美国”

希望这能帮助你理解对象以及我们为什么要将对象保持为对象。您不应该需要将对象转换为数组来访问其属性。

试试像这样的东西!

而不是像这样获取上下文:(用于获取数组索引)

$result['context']

尝试# EYZ0

$result->context

另一个例子是:(如果$result有多个数据值)

Array
(
[0] => stdClass Object
(
[id] => 15
[name] => 1 Pc Meal
[context] => 5
[restaurant_id] => 2
[items] =>
[details] => 1 Thigh (or 2 Drums) along with Taters
[nutrition_fact] => {"":""}
[servings] => menu
[availability] => 1
[has_discount] => {"menu":0}
[price] => {"menu":"8.03"}
[discounted_price] => {"menu":""}
[thumbnail] => YPenWSkFZm2BrJT4637o.jpg
[slug] => 1-pc-meal
[created_at] => 1612290600
[updated_at] => 1612463400
)


)

然后试试这个:

foreach($result as $results)
{
$results->context;
}