处理类似C#(getter&;setter)中的PHP属性


Handling PHP properties like those in C# (getter & setter)

随着时间的推移,我一直在做一些研究,想知道在PHP类中使用属性是否可以像C#一样完成,我发现了一些很好的答案和指针,但对我没有真正的帮助:

  • 我应该在PHP中使用类似C#的属性处理吗
  • 在PHP中获取并设置(私有)属性,就像在C#中一样,而不使用getter-setter魔术方法重载

尽管,正如我所说,这些都给出了很好的答案,但我仍然无法下定决心,例如,我想做一些事情,比如:

class Foo 
{
    public $bar
    {
        get { return $this->bar; }
        set { $this->bar = value; }
    }
}

但是我不能!

在PHP的限制下,最好的方法是什么?

我能想到的东西是:

class user
{
    private static $link;
    private static $init;
    private function __construct ()
    {
        global $link;
        static::$link = $link;
    }
    public static function __INIT__ ()
    {
        return static::$init = (null === static::$init ? new self() : static::$init);
    }
    public static $username;
    public function username( $value = '' )
    {
        if ( $value == '' || empty ( $value ) || !$value )
            return static::$username;
        else
            static::$username = $value;
    }
}

这就是PHP魔术方法的用途。它们允许您通过中介方法动态设置属性。在这里,让我给你看一个例子:

abstract class GetterSetterExample
{
    public function __get($name)
    {
        $method = sprintf('get%s', ucfirst($name));
        if (!method_exists($this, $method)) {
            throw new Exception();
        }
        return $this->$method();
    }
    public function __set($name, $v)
    {
        $method = sprintf('set%s', ucfirst($name));
        if (!method_exists($this, $method)) {
            throw new Exception();
        }
        $this->$method($v);
    }
}
class Cat extends GetterSetterExample
{
    protected $furColor;
    protected function getFurColor()
    {
        return $this->furColor;
    }
    protected function setFurColor($v)
    {
        $this->furColor = $v;
    }
}
$cat = new Cat();
$cat->furColor = 'black';

是的。。。这也让我害怕。

这就是为什么大多数人都满足于使用像Cat中的方法,但却是公共的。显然,有人在讨论添加"真正的"getter和setter,但那些出于可读性、语义和原则的考虑而讨厌它们的人之间似乎有很多冲突。。。

也许你需要考虑一下这是否真的必要。这只是写getter和setter的简写。

private String _name;
public String Name
{
    get
    {
        return _name;
    }
    set
    {
        _name = value;
    }
}

具有与完全相同的功能

private $_name;
public function getName()
{
    return $_name;
}
public function setName($name)
{
    $_name = $name;
}

通话中只有一个区别:

C#  : Object.Name = "This is my Name";
PHP : Object->setName ("This is my Name");

如果你真的喜欢C#语法(在我看来这只是一种习惯),我认为Flosculus的答案是唯一的选择。如果你意识到代码的作用,它就没有那么复杂了。供参考:

__set() is run when writing data to inaccessible properties.
__get() is utilized for reading data from inaccessible properties.

在本例中,furColor是不可访问的,因为它是受保护的变量。

那么这里发生了什么$cat->furColor = 'black

  • furColor不可访问,因此magic方法__set正在调用
  • 它在GetterSetterExample中创建一个名为setFurColor的setter,并检查它是否存在
  • 是的,它确实存在,因为Cat实现了它
  • 调用CCD_ 7并设置变量

最后,这段代码的作用与上面示例中的一般getter和setter完全相同。这只是一个模拟C#属性的"变通方法"。那么,回到我这个答案的第一个问题,有必要吗?在我看来,事实并非如此。PHP不支持属性,所以它没有明确的含义,为什么要尝试模拟它。一般的getter和setter是一种方法,正如我的例子所示,它做的事情完全相同。魔术方法很慢,如果你想以一种类型安全的方式来做这件事,祝你好运。Flosculus的示例代码并不复杂,但这种方法可能会变得(不必要的)复杂。