1

If I check for isset($var), I won't be able to differentiate between following 2 cases. In the first one, I am explicitly setting $t1->a to null whereas in the second, it's left unchanged.

<?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?
}

Edit : Reason I need this feature is : Before persisting an object of class Test to Database, I need to know if $a was explicitly set to null or was left unchanged. In the later case, I would set it to its default DB value as specified in the table definition.

simplfuzz
  • 12,479
  • 24
  • 84
  • 137
  • When/why do you need this? – kero Nov 15 '15 at 20:25
  • @kingkero Before persisting an object of class Test to Database, I need to know if $a was explicitly set to null or was left unchanged. In the later case, I would set it to its default DB value as specified in the table definition. – simplfuzz Nov 16 '15 at 06:38
  • Is my answer not satisfying? – kero Nov 17 '15 at 21:43

3 Answers3

2

Ok, since you are writing your own ORM, it might make sense to use the magic methods (as suggested by Machavity). You could create a parent class

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);
    }
}

and extend it

class Test extends DB_Obj {
    protected $attributes = array(
        'a' => NULL
    );
}

When you test it now like this, it works properly

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

$t2 = new Test();

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

The advantage of this is also, when you want to save it to the db, you don't need to know each attribute's name (or use another function), but can just iterate over the $attributes array.

Community
  • 1
  • 1
kero
  • 10,647
  • 5
  • 41
  • 51
0

You can see an answer here Check if value isset and null

By using 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
Community
  • 1
  • 1
Elie Faës
  • 3,215
  • 1
  • 25
  • 41
0

I would personnally create a class called UntouchedProperty and set my properties to it at instanciation. Then, untouched and set to null will be different.

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
tleb
  • 4,395
  • 3
  • 25
  • 33