为了账号安全,请及时绑定邮箱和手机立即绑定

薛定谔的属性:带有`__get()`的PHP类属性名称返回值,但也出现“不存在”错误

薛定谔的属性:带有`__get()`的PHP类属性名称返回值,但也出现“不存在”错误

PHP
忽然笑 2023-07-07 10:54:01
我有一个 PHP 7.3 中具有受保护属性的类。该类有一个__get()方法设置为返回属性,但不允许更改它们。非常基本:Class myClass {protected $name;...public function __get( $prop ) {    if ( isset( $this->$prop ) ) {        return $this->$prop;    } else {        error_log( "Call to nonexistent '$prop' property of " . __CLASS__ . " class" )        return null;    }}}我有一个对数组和对象进行排序的函数。在该代码中,我有一些选择要排序的值。如果它是一个数组,则获取该元素。如果是对象,则查找函数,如果没有函数,则查找属性:$ae = is_array( $a ) ? $a[ $arg ] :    ( is_callable( [$a, $arg] ) ? $a->$arg() :    $a->$arg );所以我运行了一个测试,调用对象的只读属性之一——“名称”。如果我直接调用它,$myObj->name将返回预期的值。$a = $myObj如果我使用and将其传递到排序函数中$arg = "name",我确实会返回该值(即,它排序正确),但我也会收到该属性不存在的错误。Call to nonexistent 'name' property of myClass class所以...“变量变量”属性名称工作正常,并且按照我的预期传递函数__get(),但它仍然会 ping 错误。薛定谔财产既存在又不存在。它触发if()中子句的两个分支__get()。注意:我将排序代码分解为多行以查明错误。它肯定在第三行—— $a->$arg。如果我将其更改为( $a->$arg ?? null )它会给出完全相同的错误。记住:它正在返回值;但同时记录一个错误,表明没有这样的值。这里发生了什么?我该如何摆脱这个错误?
查看完整描述

1 回答

?
慕桂英546537

TA贡献1848条经验 获得超10个赞

好的,发生的事情是这样的:该错误仅在排序时针对某些条目触发,而不是针对全部条目。(日志中有大量此类错误,因此仅从外观上看并不明显。)


看__get()代码:


public function __get( $prop ) {

    if ( isset( $this->$prop ) ) {

        return $this->$prop;

    } else {

        error_log( "Call to nonexistent '$prop' property of " . __CLASS__ . " class" )

        return null;

    }

}

来自数据库的一些数据具有空白字段,这对于代码来说是空的。 isset( null )是一个 false-y 值,因此elseIf 的子句在这些条目上触发。


修复?不检查isset(),检查property_exists()。


public function __get( $prop ) {

    if ( property_exists( $this, $prop ) ) {

...


查看完整回答
反对 回复 2023-07-07
  • 1 回答
  • 0 关注
  • 107 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信