Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
PHP-检查是否显式设置了类成员_Php_Oop - Fatal编程技术网

PHP-检查是否显式设置了类成员

PHP-检查是否显式设置了类成员,php,oop,Php,Oop,如果我检查isset($var),我将无法区分以下两种情况。在第一个示例中,我显式地将$t1->a设置为null,而在第二个示例中,它保持不变 <?php class Test { public $a; } $t1 = new Test(); $t1->a = null; if(isExplicitlySet($t1->a)) { echo "yes t1\n"; } $t2 = new Test(); if(isExplicitlySet($t2->a)) {

如果我检查isset($var),我将无法区分以下两种情况。在第一个示例中,我显式地将$t1->a设置为null,而在第二个示例中,它保持不变

<?php
class Test {
 public $a;
}

$t1 = new Test();
$t1->a = null;
if(isExplicitlySet($t1->a)) {
  echo "yes t1\n";
}

$t2 = new Test();
if(isExplicitlySet($t2->a)) {
  echo "yes t2\n";
}


function isExplicitlySet($var) {
//what goes here?
}

您可以在这里看到答案

通过使用get_defined_vars

$foo = NULL;
$vars = get_defined_vars();
if (array_key_exists('bar', $vars)) {}; // Should evaluate to FALSE
if (array_key_exists('foo', $vars)) {}; // Should evaluate to TRUE

我将亲自创建一个名为
untoucedProperty
的类,并在实例化时为其设置属性。然后,untouched和设置为null将是不同的

class UntouchedProperty {}

class Foo
{
    public $bar;

    public function __construct()
    {
        $this->bar = new UntouchedProperty;
    }

    public function wasTouched($property)
    {
        if ($this->$property instanceof 'UntouchedProperty') {
            return false;
        }

        return true;
    }
}

$foo = new Foo;

$foo->wasTouched('bar'); #=> false

$foo->bar = null;

$foo->wasTouched('bar'); #=> true

好的,因为您正在编写自己的ORM,所以使用神奇的方法(如所建议的)可能是有意义的。您可以创建一个父类

abstract class DB_Obj {
    protected $attributes = array();
    protected $attributes_have_been_set = array();

    public function __set($name, $value) {
        $this->attributes[$name] = $value;
        $this->attributes_have_been_set[$name] = TRUE;
    }

    public function __get($name) {
        return $this->attributes[$name];
    }

    public function __isset($name) {
        return array_key_exists($name, $this->attributes_have_been_set);
    }
}
并扩展它

class Test extends DB_Obj {
    protected $attributes = array(
        'a' => NULL
    );
}
当您现在这样测试它时,它工作正常

$t1 = new Test();
$t1->a = null;

$t2 = new Test();

var_dump( isset($t1->a), isset($t2->a) );
//        bool(true)     bool(false)

这样做的好处还在于,当您想将其保存到数据库中时,不需要知道每个属性的名称(或使用另一个函数),只需迭代
$attributes
数组。

什么时候/为什么需要它?@kingkero在将类测试对象持久化到数据库之前,我需要知道$a是显式设置为null还是保持不变。在后一种情况下,我会将其设置为表定义中指定的默认DB值。我的答案不令人满意吗?这在这里是如何应用的?