【问题标题】:PHP - Using one setter on all public properties of a classPHP - 在类的所有公共属性上使用一个 setter
【发布时间】:2012-11-08 21:01:00
【问题描述】:

似乎有很多关于 PHP 中的 setter 和 getter 的问题。但是,它们似乎都没有提到它们不适用于公共变量。

我有一系列公共变量,设置时需要同类型的数据检查(主要是strip_tags())。

在保持变量公开的同时,最高效的代码方法是什么?

似乎唯一可用的选项是为我的所有变量创建一个方法“setPropertyName”,这对我来说似乎没有必要。

感谢您的帮助。

【问题讨论】:

  • 我建议不要使用魔法方法,因为它们很慢。我建议将该字段标记为私有并编写一个 getter foreach 字段。为什么要公开您的字段?
  • 我希望能够在课堂外访问它们。
  • 如果这是唯一原因,我建议您为每个字段编写一个公共 getter 和一个公共 setter,并将该字段标记为私有。这是在 php 中执行此操作的常用方法(我几乎从不在类中拥有公共字段)

标签: php oop properties getter-setter


【解决方案1】:

实际上明确定义您的 getter 和 setter 可能是最佳实践。话虽如此,您可以使用 __set()__get() 魔术方法为从类外部(受保护和私有)无法访问的属性的请求提供通用处理。

因此,您需要做的就是将您的属性设置为受保护/私有并指定 __get()__set() 方法(如果您要使用 @ 检查属性,也可能需要 __isset()__unset() 987654327@ 或尝试unset() 属性)。

再次重申,最好的做法 (IMO) 是让所有类属性无法从类外部访问,并根据需要显式设置 setter/getter 以提供访问权限。

【讨论】:

    【解决方案2】:

    您可以尝试魔术方法__call($name,$args),这样您就不需要编写 setPropertyName 和 getPropertyName 函数了:

    function __call($name,$args){
        $variable=lcfirst(substr($name,3));
        if(!isset($this->$variable))
            return false;
        if(substr($name,0,3)=='set')
            $this->$variable=$args[0];
        else
            return $this->$variable;
        return true;
    }
    

    话虽如此,如果使用得当,魔术方法__get__set 可以很好地处理公共变量。以下是我如何使用它们:

    public $variables=array();
    function __get($name){
        return isset($this->variables[$name])?$this->variables[$name]:false;
    }
    function __set($name,$value){
        $this->variables[$name]=$value;
    }
    

    然后您可以使用$this->name; 而不是$this->getName(); 访问它们 把它们放在一起,然后你就可以随心所欲了。

    同样,这是一个骨干。如果你想去除标签,你可以把它放在 setter 或 getter 函数的代码中,或者修改调用函数来检查第二个参数,它将去除标签$this->setName($value,true);//strip tags

    【讨论】:

    • 只有当被访问的属性在当前范围内不可见时(即私有属性并在类外调用,或受保护并被调用),才调用重载魔术方法,如 __set() 和 __get()在从它继承的类或类之外)。它们不适用于公共财产。
    • 试试吧,它会工作的。我没有直接访问 $variables。 $variables 是一个存储数据的数组。可以直接访问$variables,setter和getter不起作用。
    • $class->asdf='asdf'; 设置得很好并将其存储在一个数组中,然后您可以以相同的方式检索它。如果需要,您还可以使用$class->variable['asdf']; 访问该变量。
    • 添加第二个代码示例后,您的意图变得更加清晰。我只是在评论您的说法,即魔术方法 __get__set 非常适用于公共属性。它们根本不适用于公共财产。如果你有一个公共属性并且你尝试访问它,那么魔法方法根本不会被调用。
    • 我明白,这就是为什么如果我还想以这种方式访问​​单个变量,我不会使用它的原因。无论哪种方式,我们都同意它不适用于$this->$name 意义上的公共变量。
    【解决方案3】:

    可以将它们设为私有,并使用公共 __set()__get() 获取变量(如果存在),并在设置时应用验证/清理操作。

    例如:

    class Foo {
        private $variable;
        private $otherVariable;
    
        public function __get($key) {
            return $this->$key;
        }
    
        public function __set($key, $value) {
            $this->$key = strip_tags($value);
        }
    }
    
    $foo = new Foo;
    $foo->variable = "test"; //Works.
    echo $foo->variable; //test
    

    【讨论】:

    • 我想像你一样做,但使用公共类属性。感谢您的帮助,看来我应该将我的变量设为私有。
    • @AdamCarter:如果此答案解决了您的问题,请考虑通过单击答案得分下方的绿色大勾号 (✔) 来投票并接受它。
    猜你喜欢
    • 2021-09-03
    • 2017-06-27
    • 2023-03-15
    • 2017-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 2023-04-04
    相关资源
    最近更新 更多