PHP如何使用静态类的魔术方法?

web*_*.pl 6 php static class

我正在尝试将数组转换为对象.我想使用魔术方法 - 带有静态属性的__get和__set.

我的代码:

class UserData {
    private static  $id, $name, $login;

    public function __get($var)
    {
        return self::$var;
    }
    public function __set($var, $val)
    {
        self::{$var} = $val;
    }
}
Run Code Online (Sandbox Code Playgroud)

并设置:

foreach($userArray as $key => $val) 
    {
        DaneBilingowe::${$key} = $val;
    }
Run Code Online (Sandbox Code Playgroud)

错误:致命错误:无法访问私有属性UserData :: $ id

是否可以使用具有静态属性的魔术方法?

J.M*_*ney 5

简而言之,没有.

__get()并且__set()是实例方法.它们本质上是组成的函数stdClass(),它是一个实例.

如果必须以这种方式设置静态内容,则可以为类提供stdClass参数和单例结构,以允许您神奇地设置和获取数据.

例如:

class UserData {
    protected static $_instance;
    protected $_data = array();

    public static function get_instance() {
        static $initialized = FALSE;

        if ( ! $initialized) {
            self::$_instance = new UserData;
            $initialized = TRUE;
        }

        return self::$_instance;
    }

    public function __get($var) {
        $self = self::get_instance();

        return isset($self->_data[$var]) ? $self->_data[$var] : NULL;
    }

    public function __set($var, $val) {
        $self = self::get_instance();

        $self->_data[$var] = $val;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以去:

 $UserData =& UserData::get_instance();
 $UserData->var = 'val';

 echo $UserData->var; // prints 'val'
Run Code Online (Sandbox Code Playgroud)

但是,我建议不要在PHP中使用Singletons,因为它们毫无意义.您可以在PHP单例类的最佳实践中阅读一些原因.

使用静态类或实例类.

魔术吸气剂和制定者是捷径.您可以使用普通的setter和getter实现相同的行为.下面的示例提供了相同的功能,但意图更清晰:

class UserData {
    protected $id, $name, $login;

    public static function set_name($name) {
        self::$name = $name;
    }

    public static function set_login($login) {
        self::$login = $login;
    }

    public static function get_id() {
        return self::$id;
    }

    public static function get_name() {
        return self::$name;
    }

    public static function get_login() {
        return self::login;
    }
}
Run Code Online (Sandbox Code Playgroud)

注意上面的代码$ id是不可写的.它只是可读的.$ name和$ login是可读写的.使用普通的setter和getter来控制读写是更容易和更少的错误.魔术方法只是魔法,通常魔法并不具体,在代码中也不太容易理解.

我要说的最后一点是,为什么UserData会是静态的?除非您在整个代码中只有1个用户,否则将其保持静态是没有意义的.也许我没有全面了解,但应该实例化具有id和名称的内容,以便您可以拥有多个实例.否则,为什么有id,因为类本身是唯一的.