statici variabili devono essere parte della definizione di classe, quindi non è possibile crearli in modo dinamico . Nemmeno con Reflection:
chuck at manchuck dot com 2 years ago
E 'importante notare che la chiamata ReflectionClass::setStaticPropertyValue
non vi permetterà di aggiungere nuove proprietà statiche a una classe.
Ma questo sembra molto simile a un XY Problem. Probabilmente non vuoi veramente aggiungere ad una classe PHP al runtime; avete qualche caso d'uso che potrebbe essere soddisfatta anche in questo modo. O in quel modo sarebbe il modo più veloce, se fosse disponibile, per soddisfare alcuni casi d'uso. Ci potrebbero essere altri modi.
In realtà i casi di utilizzo riportati di seguito sono ancora una volta le soluzioni possibili per alcuni problemi di livello superiore. Potrebbe valerne la pena riesaminare il problema di alto livello e rifattarlo/ripensarlo in termini diversi, magari ignorando del tutto l'intromissione di proprietà statiche.
Voglio un dizionario di proprietà all'interno della mia classe.
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');
}
voglio associare alcuni valori a una classe, o: voglio un dizionario di proprietà all'interno classe qualcun altro.
Questo in realtà è successo a me e ho trovato questa domanda mentre indagavo sui modi di farlo. Avevo bisogno di vedere, nel punto B del mio flusso di lavoro, in quale punto ("A") era stata definita una determinata classe e in quale altra parte del codice. Alla fine ho memorizzato tali informazioni in un array alimentato dal mio autoloader e ho finito per essere in grado di archiviare anche lo debug_backtrace()
al momento del primo caricamento della classe.
// 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);
voglio cambiare, non creare un proprietà esistente di una classe.
// 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);
}
Wow, questa deve essere la nuova risposta accettata. – OCDev