Php 在方法中声明受保护的变量

Php 在方法中声明受保护的变量,php,oop,class,visibility,Php,Oop,Class,Visibility,我仔细看了一下,似乎找不到这个问题的答案 基本上,我使用_call方法动态生成get和set方法,但是当声明变量时,PHP的默认值是public。是否有任何方法可以将类中的变量声明为受保护的 function __call($method, $arguments) { $prefix = strtolower(substr($method, 0, 3)); $property = strtolower(substr($method, 3)); if (empty($pr

我仔细看了一下,似乎找不到这个问题的答案

基本上,我使用_call方法动态生成get和set方法,但是当声明变量时,PHP的默认值是public。是否有任何方法可以将类中的变量声明为受保护的

function __call($method, $arguments) {
    $prefix = strtolower(substr($method, 0, 3));
    $property = strtolower(substr($method, 3));

    if (empty($prefix) || empty($property)) {
        return;
    }

    if ($prefix == "get" && isset($this->$property)) {
        return $this->$property;
    }

    if ($prefix == "set") {

        $this->$property = $arguments[0];
    }
}
是否有任何方法可以将类中的变量声明为受保护的

function __call($method, $arguments) {
    $prefix = strtolower(substr($method, 0, 3));
    $property = strtolower(substr($method, 3));

    if (empty($prefix) || empty($property)) {
        return;
    }

    if ($prefix == "get" && isset($this->$property)) {
        return $this->$property;
    }

    if ($prefix == "set") {

        $this->$property = $arguments[0];
    }
}
似乎不是这样。您可以使用,但这似乎只能有效地用于公开以前未公开的内容

<>您可能希望考虑将自动生成的属性存储在具有适当可见性的数组中。
(还有
\uuu get
\uu set
,但它们可能不适合您的需要。只有当属性丢失或无法访问时才会调用它们。能够接触受保护属性的类将绕过它们。)

一个选项是使用受保护的数组,从你的魔法设定器中设定数组中的一个元素

class MyClass {
    protected $_myProperties = array();

    public function __get($name) {
        if (isset($this->_myProperties[$name])) {
            return $this->_myProperties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value) {
        $this->_myProperties[$name] = $value;
    }

    public function __isset($name) {
        return isset($this->_myProperties[$name]);
    }
}

首先,如果没有设置前缀或属性变量,我强烈建议不要返回
。这将使调试变得非常困难。相反,替换
返回使用
抛出新的BadMethodCallException('方法不存在:'。$Method)

第二,这不是违背了保护变量的观点吗?它允许在没有任何验证的情况下读取和写入所有属性。如果你要这么做,你最好把它们公之于众

我个人发现
$foo->bar='baz'
$foo->setBar('baz')更具可读性。这并不是因为它“更容易”理解,而是因为第二个是不必要的冗长

就个人而言,我建议做一个
\uu get
\uu set
,并添加验证。保护变量的全部目的是为了信任(这样您就可以信任设置)。当然,您可以使用反射或子分类来更改它们,但我通常认为,如果有人走得那么远,如果他们弄乱了一个变量,他们应该有任何意外的自负

请记住,如果您使用的是任何一种神奇的方法,如果希望IDE向您提示方法/变量,则需要添加文档元素

编辑:


不要忘记,如果您声明
\uuu get
/
\uu set
方法,您可以在子类中重写它们。因此,如果子级声明了新变量,您可以在那里处理它们,然后调用
parent::\u get
来处理默认变量。因此,不要为了让所有子级都有一个方法而使用数组。对你知道的成员进行验证,并让你的孩子自己处理验证…

出于兴趣,你为什么要使用uuu call而不是uuu get and uu set?只是看起来更简单,我也从这里复制了它:是的,我同意你的第二段。。。将这些生成的“属性”存储在关联数组中。然后,关联数组可以是类的受保护属性。为了使用
\uu get
\uu set
我认为您需要这样做。我不同意。这违背了成员变量的观点。当类将存储未知变量(例如注册表类或类似的东西)时,我使用关联数组。但是当你有一组有限的已知变量时,为什么不使用成员变量呢?从这个问题上我只能想象,他在做一些古怪的继承和/或可见性魔术。除非上面发布的代码不完整,否则我看不到对属性进行任何转换…+1不同意$foo->setBar('baz');与$foo->bar='baz'相比,不必要的冗长;因为getter和setter方法总是允许对设置属性进行验证,而非私有属性总是可以绕过任何验证进行设置。。。但是这里有很多非常有用的信息片段,这只是我可能需要添加到类中的任何变量的回退方法。一般来说,当需要保护变量时,我总是使用get和set方法。我完全理解调试的困难,只会谨慎地使用此方法来实现DRY。我确实会不时使用
getBar()
语法,但除非它真的有意义,否则我尽量不使用。我只是不喜欢在一个类中有50个方法只是为了获取/设置成员变量而造成的混乱。。。大多数情况下,这根本不是必需的(但并非总是)…谢谢,这么做吧。工作正常,但保持了调用方法的习惯,即使用$class->getSomething();