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

我有一个 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 )它会给出完全相同的错误。记住:它正在返回值;但同时记录一个错误,表明没有这样的值。


这里发生了什么?我该如何摆脱这个错误?


忽然笑
浏览 108回答 1
1回答

慕桂英546537

好的,发生的事情是这样的:该错误仅在排序时针对某些条目触发,而不是针对全部条目。(日志中有大量此类错误,因此仅从外观上看并不明显。)看__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 ) ) {...
打开App,查看更多内容
随时随地看视频慕课网APP