如果我检查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?
}
编辑:我需要此功能的原因是:在将类Test的对象持久化到数据库之前,我需要知道$ a是否显式设置为null或保持不变。在后一种情况下,我会将其设置为表定义中指定的默认DB值。
答案 0 :(得分:2)
好的,既然您正在编写自己的ORM,那么使用魔术方法可能是有意义的(如Machavity所示)。您可以创建父类
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);
}
}
和extend
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)
这样做的好处是,当你想将它保存到数据库时,你不需要知道每个属性的名称(或使用另一个函数),但可以迭代{ {1}}数组。
答案 1 :(得分:0)
您可以在此处查看答案Check if value isset and null
使用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
答案 2 :(得分:0)
我会个人创建一个名为UntouchedProperty
的类,并在instanciation时将我的属性设置为它。然后,未触及并设置为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