2012-03-23 22 views

Respuesta

10

No sé exactamente por qué usted quiere hacer esto, pero esto funciona Tienes que acceder a las 'variables' dinámicas como una función porque todavía no hay un método mágico __getStatic() en 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

Las propiedades estáticas se deben definir en la definición de la clase. Por lo tanto, las propiedades estáticas reales no se pueden crear dinámicamente como las propiedades normales.

Por ejemplo, si ejecuta esto:

<?php 

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

MyClass::createDynamic(); 

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

... obtendrá este error

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

Observe cómo se produce el error en la línea 8 al intentar establecer la propiedad en lugar de la línea 14 o 15 (como era de esperar si lo estuvieras haciendo mal y crear propiedades estáticas dinámicamente era realmente posible).

2

variables estáticas deben ser parte de la definición de clase, por lo que no pueden crearlos dinámicamente . Ni siquiera con Reflection:

chuck at manchuck dot com            2 years ago 

Es importante señalar que llamar ReflectionClass::setStaticPropertyValue no permitirá añadir nuevas propiedades estáticas a una clase.

Pero esto se parece mucho a un XY Problem. Probablemente no desee realmente agregar propiedades estáticas a una clase PHP en tiempo de ejecución; tiene algún caso de uso que podría cumplirse también de esa manera. O de esa manera sería la forma más rápida, si estuviera disponible, para cumplir con algún caso de uso. Bien podría haber otras formas.

En realidad, los casos de uso a continuación son una vez más posibles soluciones a algún problema de nivel superior. Podría valer la pena reexaminar el problema de alto nivel y refactorizarlo/repensarlo en términos diferentes, tal vez omitiendo la necesidad de entrometerse en las propiedades estáticas.

Quiero un diccionario de propiedades dentro de mi clase.

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'); 
} 

que desea asociar algunos valores a una clase, o bien: Quiero un diccionario de propiedades dentro clase alguna de nadie más.

Esto realmente me pasó a mí y encontré esta pregunta mientras investigaba formas de hacerlo. Necesitaba ver, en el punto B de mi flujo de trabajo, en qué punto ("A") se había definido una clase determinada y por qué otra parte del código. Al final guardé esa información en una matriz alimentada por mi autocargador, y también pude almacenar el debug_backtrace() en el momento de la primera carga de la clase.

// 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); 

que quieren cambiar, no crea, una propiedadexistente de una clase.

// 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

Guau, esta debe ser la nueva respuesta aceptada. – OCDev

Cuestiones relacionadas