代码之家  ›  专栏  ›  技术社区  ›  hsz

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

  •  0
  • hsz  · 技术社区  · 14 年前

    简单类,例如:

    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 回复  |  直到 12 年前
        1
  •  0
  •   Artefacto    14 年前

    这是可能的。操作码调用 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);
        }
    

    它对对象(如主干)有这个定义:

        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 (或者如果对象是代理对象并且代理值转换为 ) empty 将返回true。但是,要利用这个优势,您必须在PHP扩展中编写一个自定义对象。

        2
  •  1
  •   Mark Baker    14 年前

    不,不能更改空函数的行为。

    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
    
        3
  •  0
  •   Wireblue    14 年前

    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