2
static variables must be part of the class definition, so you can't create them dynamically. Not even with Reflection:
静态变量必须是类定义的一部分,因此您无法动态创建它们。甚至没有反思:
chuck at manchuck dot com 2 years ago
It is important to note that calling ReflectionClass::setStaticPropertyValue
will not allow you to add new static properties to a class.
请务必注意,调用ReflectionClass :: setStaticPropertyValue将不允许您向类添加新的静态属性。
But this looks very much like a XY Problem. You probably don't really want to add static properties to a PHP class at runtime; you have some use case that could be fulfilled also that way. Or that way would be the fastest way, were it available, to fulfill some use case. There well might be other ways.
但这看起来非常像XY问题。您可能真的不想在运行时向PHP类添加静态属性;你有一些用例也可以通过这种方式实现。或者那种方式是最快的方式,如果有的话,可以实现一些用例。可能还有其他方式。
Actually the use cases below are yet again possible solutions to some higher level problem. It might be worth it to reexamine the high level problem and refactor/rethink it in different terms, maybe skipping the need of meddling with static properties altogether.
实际上,下面的用例再次成为某些更高级别问题的可能解决方案。重新审视高级问题并以不同的方式重构/重新考虑它可能是值得的,可能完全不需要干涉静态属性。
I want a dictionary of properties inside my class.
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');
}
I want to associate some values to a class, or: I want a dictionary of properties inside
some one else's class.
This actually happened to me and I found this question while investigating ways of doing it. I needed to see, in point B of my workflow, in which point ("A") a given class had been defined, and by what other part of code. In the end I stored that information into an array fed by my autoloader, and ended up being able to also store the debug_backtrace()
at the moment of class first loading.
这实际上发生在我身上,我在调查这样做的过程中发现了这个问题。我需要在工作流程的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);
I want to change, not create, an
existing property of a class.
// 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);
}