2012-01-03 22 views
42

¿Cómo puedo crear una propiedad a partir de un argumento dado dentro del método de un objeto?Cómo crear nueva propiedad dinámicamente

class Foo{ 

    public function createProperty($var_name, $val){ 
    // here how can I create a property named "$var_name" 
    // that takes $val as value? 

    } 

} 

Y yo quiero ser capaz de acceder a la propiedad como:

$object = new Foo(); 
$object->createProperty('hello', 'Hiiiiiiiiiiiiiiii'); 

echo $object->hello; 

También es posible que yo pudiera hacer que la propiedad pública/protected/privado? Sé que en este caso debería ser pública, pero puede que desee agregar algunos métodos magik para obtener propiedades protegidas y otras cosas :)


creo que he encontrado una solución:

protected $user_properties = array(); 

    public function createProperty($var_name, $val){ 
    $this->user_properties[$var_name] = $val; 

    } 

    public function __get($name){ 
    if(isset($this->user_properties[$name]) 
     return $this->user_properties[$name]; 

    } 

que hacer ¿Piensas que es una buena idea?

Respuesta

60

Hay dos métodos para hacerlo.

Uno, se pueden crear directamente la propiedad de forma dinámica desde fuera de la clase:

class Foo{ 

} 

$foo = new Foo(); 
$foo->hello = 'Something'; 

O si desea crear propiedad a través de su método de createProperty:

class Foo{ 
    public function createProperty($name, $value){ 
     $this->{$name} = $value; 
    } 
} 

$foo = new Foo(); 
$foo->createProperty('hello', 'something'); 
+0

gracias. Lo necesito dentro de la clase sin embargo. Es algo complicado de explicar, las propiedades son en realidad objetos que son extensiones de sitios que el administrador del sitio puede habilitar/deshabilitar :) Pero usaré mi solución, creo que es mejor mantenerlos dentro de una matriz. – Alex

+3

¿Es posible configurarlas como privadas o protegidas? –

+0

Establecer una propiedad como esta no nos permite hacerlo privado o protegido porque está configurado como público. Sin embargo, puede intentar trabajar con los métodos de magia OOP '__get()' y '__set()'. Consulte http://stackoverflow.com/questions/4713680/php-get-and-set-magic-methods – mauris

5

sobrecarga propiedad es muy lento. Si puedes, trata de evitarlo. También es importante implementar los otros dos métodos mágicos:

__isset(); __unset();

Si no desea encontrar algunos errores comunes más adelante, cuando el uso de estos objetos "atributos"

Éstos son algunos ejemplos:

http://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.members

editado después de que Alex comentario:

Puede verificar las diferencias de tiempo entre ambas soluciones (cambie $ REPEAT_PLEASE)

<?php 

$REPEAT_PLEASE=500000; 

class a {} 

$time = time(); 

$a = new a(); 
for($i=0;$i<$REPEAT_PLEASE;$i++) 
{ 
$a->data = 'hi'; 
$a->data = 'bye'.$a->data; 
} 

echo '"NORMAL" TIME: '.(time()-$time)."\n"; 

class b 
{ 
     function __set($name,$value) 
     { 
       $this->d[$name] = $value; 
     } 

     function __get($name) 
     { 
       return $this->d[$name]; 
     } 
} 

$time=time(); 

$a = new b(); 
for($i=0;$i<$REPEAT_PLEASE;$i++) 
{ 
$a->data = 'hi'; 
//echo $a->data; 
$a->data = 'bye'.$a->data; 
} 

echo "TIME OVERLOADING: ".(time()-$time)."\n"; 
+0

Soy un tipo adicto a __get/__set/__call. Prácticamente los utilizo en todas las clases para obtener una buena API cuando uso esa clase ... No necesité __isset hasta el momento ... ¿Puedes proporcionar un enlace o algo con algunos puntos de referencia relacionados con la sobrecarga? – Alex

+0

Lo siento por las malas noticias, pero __llamada también es muy lenta –

+0

Muestra algunas referencias/pruebas de que "la sobrecarga de propiedad es lenta". – Pacerier

4

Utilice la sintaxis: $ objeto -> {$ propiedad} donde $ propiedad es una cadena variable y $ objeto puede ser esto si está dentro de la clase o cualquier objeto de instancia

ejemplo vivo: http://sandbox.onlinephpfunctions.com/code/108f0ca2bef5cf4af8225d6a6ff11dfd0741757f

class Test{ 
    public function createProperty($propertyName, $propertyValue){ 
     $this->{$propertyName} = $propertyValue; 
    } 
} 

$test = new Test(); 
$test->createProperty('property1', '50'); 
echo $test->property1; 

Resultado: 50

+0

Esta es la respuesta que estaba buscando, ya es nuevo que solo puede hacer referencia a propiedades en objetos que no han sido declarado ... $ object-> example = "hola"; Estaba más interesado en cómo agregar dinámicamente la propiedad a un objeto, al mismo tiempo que especifica dinámicamente a qué se debe llamar la propiedad. – andmar8

1

El siguiente ejemplo es para aquellos que no quieren declarar una clase entera.

$test = (object) []; 

$prop = 'hello'; 

$test->{$prop} = 'Hiiiiiiiiiiiiiiii'; 

echo $test->hello; // prints Hiiiiiiiiiiiiiiii