简单类例如:
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 );
但不是在测试整个对象时。
答案 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扩展中编写自定义对象。