2012-03-23 15 views

risposta

10

Non so esattamente perché si vuole fare questo, ma questo funziona. Devi accedere alle "variabili" dinamiche come una funzione perché non esiste ancora un metodo magico __getStatic() in PHP.

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

Le proprietà statiche devono essere definite nella definizione di classe. Pertanto, le proprietà statiche reali non possono essere create dinamicamente come le proprietà regolari.

Ad esempio, se si esegue questo:

<?php 

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

MyClass::createDynamic(); 

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

... si otterrà questo errore

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

Notate come l'errore si verifica sulla linea 8 quando si cerca di impostare la proprietà invece della riga 14 o 15 (come potreste aspettarvi se steste semplicemente facendo qualcosa di sbagliato e la creazione dinamica di proprietà statiche fosse effettivamente possibile).

2

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); 
} 
+1

Wow, questa deve essere la nuova risposta accettata. – OCDev

Problemi correlati