PHP的静态属性的Magic __get getter

问题描述 投票:56回答:6
public static function __get($value)

不起作用,即使它确实如此,我也需要在同一个类中使用magic __get getter作为实例属性。

这可能是一个是或否的问题,所以,它有可能吗?

php oop properties getter
6个回答
59
投票

不,这是不可能的。

引用manual page of __get

成员重载仅适用于对象上下文。这些魔术方法不会在静态上下文中触发。因此这些方法不能声明为静态。

在PHP 5.3中,添加了__callStatic;但是还没有__getStatic__setStatic;即使拥有/编码它们的想法经常会回到php internals @ mailling-list上。

甚至有一个Request for Comments: Static classes for PHP 但是,仍然没有实现(还是?)


16
投票

也许有人仍然需要这个:

static public function __callStatic($method, $args) {

  if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
    $reflector = new \ReflectionClass(__CLASS__);
    $property = strtolower($match[2]). $match[3];
    if ($reflector->hasProperty($property)) {
      $property = $reflector->getProperty($property);
      switch($match[1]) {
        case 'get': return $property->getValue();
        case 'set': return $property->setValue($args[0]);
      }     
    } else throw new InvalidArgumentException("Property {$property} doesn't exist");
  }
}

4
投票

非常好mbrzuchalski。但它似乎只适用于公共变量。只需将您的开关更改为允许它访问私有/受保护的:

switch($match[1]) {
   case 'get': return self::${$property->name};
   case 'set': return self::${$property->name} = $args[0];
}

而你可能想要更改if语句以限制可访问的变量,否则它将无法使它们成为私有或受保护的目的。

if ($reflector->hasProperty($property) && in_array($property, array("allowedBVariable1", "allowedVariable2"))) {...)

因此,例如,我有一个类,旨在使用ssh pear模块从远程服务器中为我提取各种数据,我希望它根据要求查看的服务器对目标目录做出某些假设。调整版mbrzuchalski的方法是完美的。

static public function __callStatic($method, $args) {
    if (preg_match('/^([gs]et)([A-Z])(.*)$/', $method, $match)) {
        $reflector = new \ReflectionClass(__CLASS__);
        $property = strtolower($match[2]). $match[3];
        if ($reflector->hasProperty($property)) {
            if ($property == "server") {
                $property = $reflector->getProperty($property);
                switch($match[1]) {
                    case 'set':
                        self::${$property->name} = $args[0];
                        if ($args[0] == "server1") self::$targetDir = "/mnt/source/";
                        elseif($args[0] == "server2") self::$targetDir = "/source/";
                        else self::$targetDir = "/";
                    case 'get': return self::${$property->name};
                }
            } else throw new InvalidArgumentException("Property {$property} is not publicly accessible.");
        } else throw new InvalidArgumentException("Property {$property} doesn't exist.");
    }
}

1
投票

试试这个:

class nameClass{
    private static $_sData = [];
    private static $object = null;
    private $_oData = [];

    public function __construct($data=[]){
        $this->_oData = $data;
    }

    public static function setData($data=[]){
        self::$_sData = $data;
    }

    public static function Data(){
        if( empty( self::$object ) ){
            self::$object = new self( self::$_sData ); 
        }
        return self::$object;
    }

    public function __get($key) {
        if( isset($this->_oData[$key] ){
            return $this->_oData[$key];
        }
    }

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

nameClass::setData([
    'data1'=>'val1',
    'data2'=>'val2',
    'data3'=>'val3',
    'datan'=>'valn'
]);

nameClass::Data()->data1 = 'newValue';
echo(nameClass::Data()->data1);
echo(nameClass::Data()->data2);

0
投票

此外,您可以使用__get()获取访问它们的静态属性,如成员属性:

class ClassName {    
    private static $data = 'smth';

    function __get($field){
        if (isset($this->$field)){
            return $this->$field;
        }
        if(isset(self::$$field)){  
            return self::$$field;  // here you can get value of static property
        }
        return NULL;
    }
}

$obj = new ClassName();
echo $obj->data; // "smth"

0
投票

结合__callStaticcall_user_funccall_user_func_array可以访问PHP类中的静态属性

例:

class myClass {

    private static $instance;

    public function __construct() {

        if (!self::$instance) {
            self::$instance = $this;
        }

        return self::$instance;
    }

    public static function __callStatic($method, $args) {

        if (!self::$instance) {
            new self();
        }

        if (substr($method, 0, 1) == '$') {
            $method = substr($method, 1);
        }

        if ($method == 'instance') {
            return self::$instance;
        } elseif ($method == 'not_exist') {
            echo "Not implemented\n";
        }
    }

    public function myFunc() {
        echo "myFunc()\n";
    }

}

// Getting $instance
$instance = call_user_func('myClass::$instance');
$instance->myFunc();

// Access to undeclared
call_user_func('myClass::$not_exist');
© www.soinside.com 2019 - 2024. All rights reserved.