Если я проверю на 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, как указано в определении таблицы.
Хорошо, так как вы пишете свой собственный 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)
Преимущество этого также в том, что если вы хотите сохранить его в db, вам не нужно знать имя каждого атрибута (или использовать другую функцию), но он может просто перебирать массив $attributes
.
Я бы лично создал класс под названием 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
Здесь вы можете увидеть ответ. Проверьте, действительно ли значение isset и 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