95 votes

Comment ajouter une propriété à un objet en 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 bonne façon (en dehors de la déclaration de classe) d'ajouter une propriété à un objet déjà instancié ?

NOTE : Je veux que la solution fonctionne avec l'objet PHP générique de type stdClass.

Un peu de contexte sur cette question. Je suis en train de décoder une chaîne json qui est un tableau d'objets json. json_decode() génère un tableau d'objets StdClass. Je dois manipuler ces objets et ajouter une propriété à chacun d'eux.

147voto

Crontab Points 5146

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 le transformer à nouveau en objet. Le seul cas où vous rencontrez stdClass (je crois), c'est lorsque vous transformez un tableau en objet ou lorsque vous créez un nouveau tableau. stdClass à partir de zéro (et bien sûr lorsque vous json_decode() quelque chose - je suis bête de l'avoir oublié !).

Au lieu de :

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

Vous feriez :

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

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

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

Également en tant que 1 liner :

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

138voto

JM R. Points 1311

Faites comme ça :

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

Essayez maintenant :

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

11voto

Rocket Hazmat Points 87407

Si vous voulez éditer le JSON décodé, essayez de l'obtenir sous forme de tableau associatif au lieu d'un tableau d'objets.

$data = json_decode($json, TRUE);

6voto

Ragnar Points 896

C'est un autre moyen :

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

echo $foo->bar; //12345

1voto

Benjamin Dubois Points 961

Vous devez utiliser les méthodes magiques __Set et __get. Un 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 car il n'y a pas de sécurité du tout :)

EDIT : vu vos commentaires, voici peut-être 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...

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