2009-08-14 8 views

Odpowiedz

54

Nie, to niemożliwe.

Cytowanie manual page of __get:

Członek przeciążenie działa tylko w kontekście obiektu. Te magiczne metody nie zostaną uruchomione w kontekście statycznym . Dlatego te metody nie mogą być zadeklarowane jako statyczne.


W PHP 5.3 __callStatic dodano; ale nie ma jeszcze żadnego __getStatic; nawet jeśli pomysł ich/kodowania często wraca na php internals @ mailling-list.

Jest nawet Request for Comments: Static classes for PHP
Ale jeszcze nie wdrożone (jeszcze?)

+13

To dlatego nie możemy mieć ładny rzeczy ... – cvsguimaraes

+9

statystyka @cvsguimaraes nie są ładne rzeczy ... –

+2

@webarto zgodził się, ale biorąc pod uwagę, że jesteśmy w kraju PHP, są najwyższej klasy funkcje OOP haha ​​ – cvsguimaraes

16

Może ktoś jeszcze trzeba to:

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

Co to oznacza? – starbeamrainbowlabs

4

Bardzo ładne mbrzuchalski. Ale wydaje się, że działa tylko na zmiennych publicznych. Wystarczy zmienić przełącznik do tego, aby umożliwić mu dostęp do prywatnych/protected te:

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

A ty pewnie chcesz zmienić oświadczenie if ograniczyć zmienne, które są dostępne, albo byłoby pokonać cel posiadanie ich jako prywatnych lub chronionych.

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

Tak na przykład mam klasy zaprojektowane, aby wyciągnąć różne dane dla mnie z odległym serwerem przy użyciu modułu ssh gruszka, i chcę dokonać pewnych założeń dotyczących katalogu docelowego na podstawie tego, co serwer to poproszony o spojrzenie. Udoskonalona wersja metody mbrzuchalskiego jest do tego idealna.

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."); 
    } 
} 
0

Ponadto, można uzyskać dostęp do właściwości statycznych jak ich właściwości członkowskich, wykorzystując __get():

class ClassName { 

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" 
+3

oprócz tego, że teraz jest publiczne, więc nie potrzebujesz nawet '__get' –

0

spróbuj tego:

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); 
Powiązane problemy