1 votes

Comment créer une nouvelle propriété de manière dynamique

Comment puis-je créer une propriété à partir d'un argument donné à l'intérieur d'une méthode d'un objet ?

class Foo{

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

  }

}

Et je veux pouvoir accéder à la propriété comme :

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

echo $object->hello;

Est-il également possible de rendre la propriété publique/protégée/privée ? Je sais que dans ce cas, elle devrait être publique, mais je pourrais vouloir ajouter quelques méthodes magiques pour obtenir des propriétés protégées et autres :)


Je pense avoir trouvé une solution :

  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];

  }

pensez-vous que c'est une bonne idée ?

122voto

mauris Points 19666

Il y a deux méthodes pour le faire.

Premièrement, vous pouvez directement créer une propriété de manière dynamique depuis l'extérieur de la classe :

class Foo{

}

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

Ou si vous souhaitez créer des biens par le biais de votre createProperty méthode :

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

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

20voto

crownlessking Points 11

L'exemple suivant est destiné à ceux qui ne veulent pas déclarer une classe entière.

$test = (object) [];

$prop = 'hello';

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

echo $test->hello; // prints Hiiiiiiiiiiiiiiii

7voto

Abraham Covelo Points 312

La surcharge de la propriété est très lente. Si vous le pouvez, essayez de l'éviter. Il est également important d'implémenter les deux autres méthodes magiques :

__isset() ; __unset() ;

Si vous ne voulez pas vous retrouver plus tard face à des erreurs courantes lors de l'utilisation de ces "attributs" d'objets

Voici quelques exemples :

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

EDITION après le commentaire d'Alex :

Vous pouvez vérifier vous-même les différences de temps entre les deux solutions (changer $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";

6voto

Blizzard Points 141

Utilisez la syntaxe : $objet->{$propriété} où $property est une variable de type chaîne et $object peut être ceci s'il se trouve à l'intérieur de la classe ou de tout objet d'instance

Exemple concret : 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;

Résultat : 50

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X