Esto tiene que ser simple, pero me parece que no puede encontrar una respuesta….

Tengo un genérico stdClass object $foo sin propiedades. Quiero agregar una nueva propiedad $bar que no está definido. Si hago esto:

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

PHP en modo estricto, se queja.

Cuál es la forma correcta (fuera de la declaración de la clase) para agregar una propiedad a un objeto instanciado?

NOTA: quiero que la solución para que funcione con el genérico de PHP objeto de tipo stdClass.

Un poco de historia sobre este tema. Yo soy la decodificación de una cadena json que es un array de objetos json. json_decode() genera una matriz de StdClass object. Necesito manipular estos objetos y agregar una propiedad a cada uno de ellos.

  • Intentar pasar TRUE como un 2do parámetro para json_decode. Obtendrás una matriz asociativa en lugar de una matriz de objetos.
  • PHP en modo estricto, no se quejan de eso. 3v4l.org/kn0hi
  • No sé por qué esto ha sido cerrado ya que esto es perfectamente válida la pregunta. Tengo exactamente una pregunta similar ahora.
InformationsquelleAutor Ray | 2012-07-23

7 Comentarios

  1. 104

    Si es absolutamente necesario añadir la propiedad del objeto, creo que podría lanzarla como una matriz, agregar su propiedad (como una nueva clave del array), luego se echó hacia atrás como un objeto. La única vez en que stdClass objetos (creo) es cuando lanzas una matriz como un objeto o cuando se crea un nuevo stdClass objeto desde cero (y por supuesto, cuando usted json_decode() algo – tonto de mí para olvidar!).

    Lugar de:

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

    Te gustaría hacer:

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

    O si ya había una existente stdClass object:

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

    También como un 1 forro:

    $foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );
    • Un lugar que encuentro StdClass es cuando interpreta json, que es bastante común.
    • Estoy sacudiendo mi cabeza con tristeza que no pienso mencionar que. =)
    • Su solución funciona, pero me duele mi OO corazón 🙂 Estaba esperando algún tipo de llamativos reflexión kung foo o algo… Va a mantener abierta la pregunta un poco más de tiempo y de esperanza para algunos poco conocidos PHP magia.
    • jejeje… me gustaría tener algo más elegante para usted. Por cierto, establecer explícitamente error_reporting(E_STRICT); en PHP 5.3.15-1~dotdeb.0 with Suhosin-Patch, no me da errores o avisos cuando se intenta establecer una propiedad inexistente en un stdClass object. ¿Qué versión de PHP está utilizando?
    • Ha, casi tres años después y me sale un drive-by downvote con ninguna explicación por alguna razón. Gracias.
  2. 77

    Hacerlo así:

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

    ahora intenta:

    echo $foo->bar; //should display 1234
    • La mejor respuesta para mí. Lo más bonito, y más claro.
    • Funciona como un encanto. Esta debe ser la solución aceptada.
    • ¿Cómo agregar una propiedad a un campo de un objeto utilizando esta sintaxis?
    • ‘Intento de asignar la propiedad de no-objeto» Error en Laravel
    • incluso la «barra» de la cadena puede ser en una variable: $foo->{$any_variable} = ‘1234’;
  3. 11

    Si quieres editar el decodificado JSON, trate de conseguir como un array asociativo en lugar de una matriz de objetos.

    $data = json_decode($json, TRUE);
  4. 2

    Yo siempre uso esta manera:

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

    usted debe usar la magia métodos __Set y __llegar. Ejemplo sencillo:

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

    Por supuesto, no utilizar este ejemplo como este : no hay seguridad en todo 🙂

    EDIT : visto sus comentarios, aquí podría ser una alternativa basada en la reflexión y un decorador :

     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 : no me pongas a prueba mi código, sólo la idea general…

    • Benjamin, quiero usar PHP genérico de la clase de objeto: StdClass. No puedo modificar esta clase.
    • Ray, he actualizado mi respuesta con una solución correspondiente a su necesidad, pero es pesado :-/
  6. 0

    No sé si es la versión más reciente de php, pero esto funciona. Estoy usando 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();

    Este es el resultado. El método save en realidad tiene la nueva propiedad

        Person Object
        (
           [name] => Ganga
           [age] => 23
        )
  7. -4

    Sí, es posible agregar dinámicamente las propiedades de un objeto PHP.

    Esto es útil cuando un parcial de objeto es recibido desde javascript.

    JAVASCRIPT lado:

    var myObject = { name = "myName" };
    $.ajax({ type: "POST", url: "index.php",
        data: myObject, dataType: "json",
        contentType: "application/json;charset=utf-8"
    }).success(function(datareceived){
        if(datareceived.id >= 0 ) { /* the id property has dynamically added on server side via PHP */ }
    });

    PHP lado:

    $requestString = file_get_contents('php://input');
    $myObject = json_decode($requestString); //same object as was sent in the ajax call
    $myObject->id = 30; //This will dynamicaly add the id property to the myObject object

    O SIMPLEMENTE ENVIAR UN muñeco de PROPIEDAD de javascript que se llene en PHP.

    • Creo que el envío de un ficticio propiedad de JS y rellenar en PHP lado es la más fácil, más inteligente solución. Gracias!
    • o_O O_o o_O O_o

Dejar respuesta

Please enter your comment!
Please enter your name here