web-dev-qa-db-fra.com

Comment ajouter une propriété à un objet dans PHP > = 5.3 mode strict sans générer d'erreur

Cela doit être simple, mais je n'arrive pas à trouver de réponse ...

J'ai un objet générique stdClass $foo sans propriétés. Je veux ajouter une nouvelle propriété $bar qui n'est pas déjà définie. Si je fais ça:

$foo = new StdClass();
$foo->bar = '1234';

PHP en mode strict se plaint. 

Quelle est la manière appropriée (en dehors de la déclaration de classe) d’ajouter une propriété à un objet déjà instancié?

REMARQUE: je souhaite que la solution fonctionne avec l'objet générique PHP de type stdClass.

Un peu de contexte sur cette question. Je décode une chaîne JSON qui est un tableau d'objets JSON. json_decode() génère un tableau d'objets StdClass. J'ai besoin de manipuler ces objets et d'ajouter une propriété à chacun d'eux.

60
Ray

Si vous devez absolument ajouter la propriété à l'objet, je pense que vous pouvez le transformer en tableau, ajouter votre propriété (en tant que nouvelle clé de tableau), puis la reconvertir en objet. La seule fois où vous rencontrez des objets stdClass (je crois), c’est lorsque vous transformez un tableau en objet ou lorsque vous créez un nouvel objet stdClass (et bien sûr, lorsque vous json_decode() quelque chose - ça me rend bête d’oublier!).

Au lieu de:

$foo = new StdClass();
$foo->bar = '1234';

Tu ferais:

$foo = array('bar' => '1234');
$foo = (object)$foo;

Ou si vous avez déjà un objet stdClass existant:

$foo = (array)$foo;
$foo['bar'] = '1234';
$foo = (object)$foo;

Également en 1 doublure:

$foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );
90
Crontab

Fais-le comme ça:

$foo = new StdClass();
$foo->{"bar"} = '1234';

maintenant essaye:

echo $foo->bar; // should display 1234
58
jmnerd

Si vous souhaitez modifier le JSON décodé, essayez de le convertir en tant que tableau associatif au lieu d'un tableau d'objets.

$data = json_decode($json, TRUE);
11
Rocket Hazmat

J'utilise toujours de cette façon:

$foo = (object)null; //create an empty object
$foo->bar = "12345";

echo $foo->bar; //12345
2
Ragnar

vous devriez utiliser les méthodes magiques __Set et __get. Exemple simple: 

class Foo
{
    //This array stores your properties
private $content = array();

public function __set($key, $value)
{
            //Perform data validation here before inserting data
    $this->content[$key] = $value;
    return $this;
}

public function __get($value)
{       //You might want to check that the data exists here
    return $this->$content[$value];
}

}

Bien sûr, n'utilisez pas cet exemple comme ceci: pas de sécurité du tout :) 

EDIT: vu vos commentaires, voici une alternative basée sur la réflexion et un décorateur:

 class Foo
 {
private $content = array();
private $stdInstance;

public function __construct($stdInstance)
{
    $this->stdInstance = $stdInstance;
}

public function __set($key, $value)
{
    //Reflection for the stdClass object
    $ref = new ReflectionClass($this->stdInstance);
    //Fetch the props of the object

    $props = $ref->getProperties();

    if (in_array($key, $props)) {
        $this->stdInstance->$key = $value;
    } else {
        $this->content[$key] = $value;
    }
    return $this;
}

public function __get($value)
{
    //Search first your array as it is faster than using reflection
    if (array_key_exists($value, $this->content))
    {
        return $this->content[$value];
    } else {
        $ref = new ReflectionClass($this->stdInstance);

        //Fetch the props of the object
        $props = $ref->getProperties();

        if (in_array($value, $props)) {

        return $this->stdInstance->$value;
    } else {
        throw new \Exception('No prop in here...');
    }
}
 }
}

PS: Je n'ai pas testé mon code, juste l'idée générale ...

1
Benjamin Dubois

Je ne sais pas si c'est la version la plus récente de php, mais cela fonctionne. J'utilise php 5.6

    <?php
    class Person
    {
       public $name;

       public function save()
       {
          print_r($this);
       }
    }

   $p = new Person;
   $p->name = "Ganga";
   $p->age = 23;

   $p->save();

C'est le résultat. La méthode save récupère réellement la nouvelle propriété

    Person Object
    (
       [name] => Ganga
       [age] => 23
    )
0
Ganga