简体   繁体   English

PHP-检查是否明确设置了类成员

[英]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. 如果我检查isset($ var),将无法区分以下两种情况。 In the first one, I am explicitly setting $t1->a to null whereas in the second, it's left unchanged. 在第一个中,我将$ 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?
}

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. 编辑:原因我需要此功能是:在将Test类持久化到数据库之前,我需要知道$ a是否显式设置为null或保持不变。 In the later case, I would set it to its default DB value as specified in the table definition. 在后一种情况下,我将其设置为表定义中指定的默认DB值。

Ok, since you are writing your own ORM, it might make sense to use the magic methods (as suggested by Machavity ). 好的,因为您正在编写自己的ORM,所以使用魔术方法(如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 extend

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. 这样做的好处还在于,当您要将其保存到数据库时,不需要知道每个属性的名称(或使用另一个函数),而只需遍历$attributes数组即可。

You can see an answer here Check if value isset and null 您可以在此处查看答案检查值是否设置为null

By using get_defined_vars 通过使用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

I would personnally create a class called UntouchedProperty and set my properties to it at instanciation. 我会personnally创建一个名为类UntouchedProperty和instanciation设置我的属性吧。 Then, untouched and set to null will be different. 然后,未更改并将其设置为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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM