Php 有没有更好的方法来定义uuu get而不使用变量或所有成员变量的数组?

Php 有没有更好的方法来定义uuu get而不使用变量或所有成员变量的数组?,php,Php,我正在创建一个BaseModel类,希望使用神奇的方法uu set和u get,而不是为每个属性定义setter和getter 我目前正在使用变量,因为我无法通过谷歌搜索找到其他方法。变量被认为是不好的做法,还是我什么都不担心 abstract class BaseModel implements \ArrayAccess { /** * Don't allow these member variables to be written by __set * * @var array *

我正在创建一个BaseModel类,希望使用神奇的方法uu set和u get,而不是为每个属性定义setter和getter

我目前正在使用变量,因为我无法通过谷歌搜索找到其他方法。变量被认为是不好的做法,还是我什么都不担心

abstract class BaseModel implements \ArrayAccess {

/**
 * Don't allow these member variables to be written by __set
 *
 * @var array
 */
protected $noSet = array();

/**
 * Don't allow these member variables to be retrieved by __get
 *
 * @var array
 */
protected $noGet = array();

public function offsetExists( $offset )
{
    return property_exists($this, $offset);
}
public function offsetGet( $offset )
{
    return $this->__get($offset);
}
public function offsetSet( $offset , $value )
{
    return $this->__set($offset, $value);
}
public function offsetUnset( $offset )
{
    unset($this->$offset);
}

public function __get($member)
{
    if( $member == 'noSet' || $member == 'noGet')
    {
        throw new \InvalidArgumentException ("Tried to access a forbidden property", 1);
    }

    if( ! property_exists($this, $member))
    {
        throw new \InvalidArgumentException ("Tried to access a non-existent property", 1);
    }

    if( in_array($member, $this->noGet))
    {
        throw new \InvalidArgumentException ("Tried to access a forbidden property", 1);
    }

    return $this->$member;
}

public function __set($member, $value)
{
    if( $member == 'noSet' || $member == 'noGet')
    {
        throw new \DomainException ("Tried write to a non-writable property.", 1);
    }

    if( ! property_exists($this, $member))
    {
        throw new \InvalidArgumentException ("Tried to access a non-existent property", 1);
    }

    if( in_array($member, $this->noSet))
    {
        throw new \DomainException ("Tried write to a non-writable property.", 1);
    }

    return $this->$member = $value;
}

变量确实是一种方法。

首先,您似乎认为
受保护的
关键字使属性无法使用神奇的方法设置/获取。事实并非如此。这使得您无法从类的作用域之外直接访问/修改这些属性(即,您不能执行类似于
$object->foo='bar'
)的操作)

第二,你似乎对魔法的方法有误解。实际上,当用户试图直接访问/修改属性时,它们所做的是强制执行行为。在我的示例中,如果用户尝试执行以下操作:

$object->foo = 'bar';
这实际上是调用
\u set()
方法,相当于:

$object->__set('foo', 'bar');
因此,使用get/set magic方法的典型类实现可能如下所示:

class some_class {
    protected $foo;
    protected $foo2;
    public $pub;
    public function __construct() {
        // maybe do something here
    }
    public function __get($prop) {
        if(!property_exists($this, $prop) {
            throw new Exception('Tried to get unknown property ' . $prop);
        } else {
            return $this->{$prop};
        }
    }
    public function __set($prop, $value) {
        if(!property_exists($this, $prop) {
            throw new Exception('Tried to set unknown property ' . $prop);
        } else {
            $this->{$prop} = $value;
            return true; // or whatever you want to return
        }
    }
}
用法如下:

$object = new some_class();
$object->foo = 'bar'; // sets 'bar'
echo $object->foo; // echo 'bar;
var_dump($object->foo2); // null
$object->pub = 'something'; // does not call __set() as this property is available from global scope
echo $object->pub; // echo 'something' does not call __get() as this property is available from global scope
$object->no_prop; // throws Exception from __get() as property does not exist
试图从类中实际调用
\uu get()
\uu set()
似乎是一种奇怪的用法

有关更多信息,请参阅关于对象重载的PHP文档:


PS:退房,打电话。我们去掉了模型中的太多错误:)
offsetExists
,其他的
offset*
方法是@zzzzBov的一部分。@zzzzBov我之前没有注意到
实现了
声明。删除了对该方法的评论。