PHP警告 - 未定义的属性:stdClass - 如何修复?

75

我在错误日志中看到了这个警告,想知道如何在我的代码中解决这个问题。

警告: PHP Notice: Undefined property: stdClass::$records in script.php on line 440

一些代码:

// Parse object to get account id's
// The response doesn't have the records attribute sometimes.
$role_arr = getRole($response->records);  // Line 440 

如果存在记录,则返回响应

stdClass Object
(
    [done] => 1
    [queryLocator] =>
    [records] => Array
        (
            [0] => stdClass Object
                (
                    [type] => User
                    [Id] =>
                    [any] => stdClass Object
                        (
                            [type] => My Role
                            [Id] =>
                            [any] => <sf:Name>My Name</sf:Name>
                        )

                )

        )

    [size] => 1
)

记录不存在时的响应

stdClass Object
(
    [done] => 1
    [queryLocator] =>
    [size] => 0
)

我在思考类似于array_key_exists()的对象功能,有没有这样的东西?或者我的思路错了?

解释一下,我故意关闭了这个页面并打开了一个更新的页面。虽然表面上看起来有些违反直觉,但在 Stack Overflow 上,推荐优先考虑内容更好的页面,而不是简单地保留最早的页面。 - mickmackusa
8个回答

160
if(isset($response->records))
    print "we've got records!";

可以使用“或”吗?例如:$foo = $bar->foo or "default"; - Hontoni
1
我该如何在foreach中使用这个解决方案?例如:foreach($product->images as $images) - user9696479

8

isset() 对于顶层数据可以使用,但 empty() 更适合用于查找嵌套值是否已设置。例如:

if(isset($json['foo'] && isset($json['foo']['bar'])) {
    $value = $json['foo']['bar']
}

或者:

if (!empty($json['foo']['bar']) {
    $value = $json['foo']['bar']
}

if(isset($json['foo'] && isset($json['foo']['bar'])) { is performing a needless check. Besides the fact that isset() could happily receive both of the variables in a single call, just check for the deeper element that you intend to access. if(isset($json['foo']['bar'])) { - mickmackusa
1
@mickmackusa - 是的。我不知道为什么6年前会有那种看法,但事实就是这样。我认为isset()函数从5.X到现在的行为没有改变,但无论如何,你说的是正确的。 - markdwhite
@markdwhite 我也以为它和你一样工作。结果发现在5.4中已经改变了,变得相同了。我猜我们都老了 ;) - Paul Phillips
我同意检查两个变量是不必要的,但如果你需要的话,你可以只使用一个isset -> isset($json['foo'], $json['bar']) - Don Viegues

8
在这种情况下,我会使用:
if (!empty($response->records)) {
 // do something
}

如果该属性不存在,您将不会收到任何难看的通知,并且您将知道您实际上有一些可用的记录,即$response->records 不是空数组、NULL、FALSE或其他空值。


5

2
如果您想使用property_exists,则需要使用get_class()获取类的名称。
在这种情况下,它应该是:
 if( property_exists( get_class($response), 'records' ) ){
       $role_arr = getRole($response->records);
 }
 else
 {
       ...
 }

2
空合并运算符
你可以使用isset_ternary运算符`??`。这样可以避免警告并在一行代码中分配默认值。
$role_arr = getRole($response->records ?? null);

错误控制运算符
如果预期会出现警告,您可以使用error control operator @来抑制抛出的消息。
$role_arr = getRole(@$response->records);

尽管这样可以减少代码中的混乱,但你应该谨慎使用,因为它可能会使以后的错误调试更加困难。一个使用 @ 可能有用的例子是在从用户输入创建对象并在将其用于进一步逻辑之前运行验证方法。


2
  1. 我绝不会推荐使用“闭嘴运算符”(@) - 我从不在自己的代码中使用它,因为它表明开发人员懒惰地选择不正确地处理问题。
  2. 如果 getRole() 函数期望接收一个可迭代类型的值,则传递 null 不是个好主意 - 如果没有深入了解应用程序,最好回退到 [](一个空数组)。 也就是说,我绝对支持使用“空合并运算符”(??)的建议。
- mickmackusa

1

响应本身似乎具有记录的大小。您可以使用它来检查记录是否存在。类似于:

if($response->size > 0){
    $role_arr = getRole($response->records);
}

这是最轻量/最直接的方法,如果你只想在有记录需要处理时声明$role_arr$response对象似乎无条件地提供了size属性,因此可以使用它等更多内容。请注意,使用if ($response->size) {也可以实现相同的效果,因为0是假值。 - mickmackusa

0
如果认为这个会起作用:
if(sizeof($response->records)>0)
$role_arr = getRole($response->records);

新定义的属性也包括在内。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接