simplfuzz
simplfuzz

Reputation: 12905

PHP - Check if a class member is explicitly set or not

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.

Upvotes: 1

Views: 254

Answers (3)

kero
kero

Reputation: 10638

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.

Upvotes: 2

tleb
tleb

Reputation: 4596

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

Upvotes: 0

Elie Fa&#235;s
Elie Fa&#235;s

Reputation: 3315

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

Upvotes: 0

Related Questions