我想要做這樣的事情:如何在運行時(動態)創建PHP靜態類屬性?
public static function createDynamic(){
$mydynamicvar = 'module';
self::$mydynamicvar = $value;
}
,並能夠從類中有
$value = self::$module;
我想要做這樣的事情:如何在運行時(動態)創建PHP靜態類屬性?
public static function createDynamic(){
$mydynamicvar = 'module';
self::$mydynamicvar = $value;
}
,並能夠從類中有
$value = self::$module;
訪問屬性我完全不知道你爲什麼會想這樣做這個,但是這個工作。您必須像訪問函數一樣訪問動態「變量」,因爲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();
靜態屬性必須在類定義中定義。因此,真正的靜態屬性不能像常規屬性那樣動態創建。
例如,如果您運行此:
<?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行(正如你所期望的,如果你只是做錯了,動態創建靜態屬性實際上是可能的)。
靜態變量必須是類定義的一部分,因此您無法創建它們動態。甚至就連與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);
}
哇,這需要是新接受的答案。 – OCDev 2016-07-21 12:19:19