对对象强制执行empty()测试的结果

时间:2010-06-16 10:36:02

标签: php oop

简单类例如:

class Foo
{
    protected $_bar;

    public function setBar( $value ) {

        $this->_bar = $value;

    }

}

以下是问题:

$obj = new Foo();

  var_dump( empty( $obj ) );  // true

$obj->setBar( 'foobar' );

  var_dump( empty( $obj ) );  // false

是否可以通过使用empty()函数对其进行测试来更改类的行为,以便在对象未填充数据时返回true

我知道魔术函数__isset( $name ),但只有当我们测试特定字段时才会调用它:

empty( $obj->someField );

但不是在测试整个对象时。

3 个答案:

答案 0 :(得分:1)

不,你不能改变空函数的行为。

class Foo
{
    private $_empty = true;

    protected $_bar;

    public function setBar( $value ) {
        $this->_bar = $value;
        $this->_empty = false;
    }

    public function isEmpty() {
        return $this->_empty;
    }

}


$obj = new Foo();
    var_dump( $obj->isEmpty() );  // true

$obj->setBar( 'foobar' );
    var_dump( $obj->isEmpty() );  // false

答案 1 :(得分:0)

PHP 5+应始终将具有或不具有属性的对象视为非空。我刚刚在PHP 5.3.2服务器上测试了上面的代码,var_dump在两种情况下都返回FALSE(这是正确的)。您使用的是哪个版本的PHP?

修改 PHP的“空”行为无法更改。您可以使用自己的空检查功能。试试这个:

function is_empty($object) {
    $object = (array)$object;
    foreach ($object as $key => $value) {
        if (!empty($value)) return FALSE;
    }
    return TRUE;
}

$obj = new Foo();   
var_dump(is_empty($obj)); // true
$obj->setBar('foobar');
var_dump(is_empty($obj)); // false

答案 2 :(得分:0)

有可能。操作码调用i_zend_is_true

    if (!isset || !i_zend_is_true(*value)) {
        ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 1);
    } else {
        ZVAL_BOOL(&EX_T(opline->result.var).tmp_var, 0);
    }

具有对象的这个定义(从trunk开始):

    case IS_OBJECT:
        if(IS_ZEND_STD_OBJECT(*op)) {
            TSRMLS_FETCH();

            if (Z_OBJ_HT_P(op)->cast_object) {
                zval tmp;
                if (Z_OBJ_HT_P(op)->cast_object(op, &tmp, IS_BOOL TSRMLS_CC) == SUCCESS) {
                    result = Z_LVAL(tmp);
                    break;
                }
            } else if (Z_OBJ_HT_P(op)->get) {
                zval *tmp = Z_OBJ_HT_P(op)->get(op TSRMLS_CC);
                if(Z_TYPE_P(tmp) != IS_OBJECT) {
                    /* for safety - avoid loop */
                    convert_to_boolean(tmp);
                    result = Z_LVAL_P(tmp);
                    zval_ptr_dtor(&tmp);
                    break;
                }
            }
        }
        result = 1;
        break;

因此,如果对bool的强制转换导致值为false(或者如果对象是代理对象且代理值转换为false),则empty将返回true。但是,要利用这一点,您必须在PHP扩展中编写自定义对象。