2012-03-23 106 views

回答

10

訪問屬性我完全不知道你爲什麼會想這樣做這個,但是這個工作。您必須像訪問函數一樣訪問動態「變量」,因爲PHP中沒有__getStatic()魔術方法。

class myclass{ 
    static $myvariablearray = array(); 

    public static function createDynamic($variable, $value){ 
     self::$myvariablearray[$variable] = $value; 
    } 

    public static function __callstatic($name, $arguments){ 
     return self::$myvariablearray[$name]; 
    } 
} 

myclass::createDynamic('module', 'test'); 
echo myclass::module(); 
2

靜態屬性必須在類定義中定義。因此,真正的靜態屬性不能像常規屬性那樣動態創建。

例如,如果您運行此:

<?php 

class MyClass 
{ 
    public static function createDynamic() 
    { 
     $mydynamicvar = 'module'; 
     self::$mydynamicvar = $value; 
    } 
} 

MyClass::createDynamic(); 

var_dump(MyClass::$mydynamicvar); 
var_dump(MyClass::$module); 

...你會得到這個錯誤

Fatal error: Access to undeclared static property: MyClass::$mydynamicvar test.php on line 8 

注意如何在第8行嘗試設置屬性,而不是在發生錯誤14行或15行(正如你所期望的,如果你只是做錯了,動態創建靜態屬性實際上是可能的)。

2

靜態變量必須是類定義的一部分,因此您無法創建它們動態。甚至就連與Reflection

chuck at manchuck dot com            2 years ago 

需要注意的是調用ReflectionClass::setStaticPropertyValue不會讓你新的靜態屬性添加到一個類是很重要的。

但是這看起來很像XY Problem。您可能並不真想在運行時向PHP類添加靜態屬性;你有一些可以實現的用例那樣。或者這種方式將是最快的方式,如果可用的話,可以滿足某些用例。可能還有其他方法。

實際上,下面的用例也是解決某些更高級別問題的可能解決方案。重新審視高層次問題並用不同的方式重構/重新思考它可能是值得的,可能會忽略干預靜態屬性的需要。

我想要我的班級內的屬性詞典。

trait HasDictionary { 
    private static $keyValueDictionary = [ ]; 

    public static function propget($name) { 
     if (!array_key_exists($name, static::$keyValueDictionary) { 
      return null; 
     } 
     return static::$keyValueDictionary[$name]; 
    } 

    public static function propset($name, $value) { 
     if (array_key_exists($name, static::$keyValueDictionary) { 
      $prev = static::$keyValueDictionary[$name]; 
     } else { 
      $prev = null; 
     } 
     static::$keyValueDictionary[$name] = $value; 
     return $prev; 
    } 
} 


class MyClass 
{ 
    use Traits\HasDictionary; 

    ...$a = self::propget('something'); 

    self::propset('something', 'some value'); 
} 

我想一些值一類關聯,或者:我想裏面另外一個人的類屬性的字典。

這實際上發生在我身上,我在研究這種方法時發現了這個問題。我需要在我的工作流程的B點中看到已定義給定類的點(「A」)以及代碼的其他部分。最後,我將這些信息存儲到由我的自動加載器提供的數組中,最後在第一次加載時就可以存儲debug_backtrace()

// Solution: store values somewhere else that you control. 

class ClassPropertySingletonMap { 
    use Traits\HasDictionary; // same as before 

    public static function setClassProp($className, $prop, $value) { 
     return self::propset("{$className}::{$prop}", $value); 
    } 

    public static function getClassProp($className, $prop) { 
     return self::propget("{$className}::{$prop}"); 
    } 
} 

// Instead of 
// $a = SomeClass::$someName; 
// SomeClass::$someName = $b; 

// we'll use 
// $a = ClassPropertySingletonMap::getClassProp('SomeClass','someName'); 
// ClassPropertySingletonMap::setClassProp('SomeClass','someName', $b); 

我想改變,而不是創建一個類的現有財產。

// Use Reflection. The property is assumed private, for were it public 
// you could do it as Class::$property = $whatever; 

function setPrivateStaticProperty($class, $property, $value) { 
    $reflector = new \ReflectionClass($class); 
    $reflector->getProperty($property)->setAccessible(true); 
    $reflector->setStaticPropertyValue($property, $value); 
    $reflector->getProperty($property)->setAccessible(false); 
} 
+1

哇,這需要是新接受的答案。 – OCDev 2016-07-21 12:19:19