Esto tiene que ser simple, pero parece que no puedo encontrar una respuesta ...
Tengo un objeto stdClass genérico $foo
sin propiedades. Quiero agregarle una nueva propiedad $bar
que aún no está definida. 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 clase) para agregar una propiedad a un objeto ya instanciado?
NOTA: Quiero que la solución funcione con el objeto PHP genérico de tipo stdClass.
Un poco de historia sobre este tema. Estoy decodificando una cadena json que es una matriz de objetos json. json_decode()
genera una matriz de objeto StdClass. Necesito manipular estos objetos y agregar una propiedad a cada uno.
TRUE
como segundo parámetro ajson_decode
. Le dará una matriz asociativa en lugar de una matriz de objetos.Respuestas:
Si es absolutamente necesario agregar la propiedad al objeto, creo que podría convertirlo en una matriz, agregar su propiedad (como una nueva clave de matriz) y luego devolverla como un objeto. La única vez que te encuentras con
stdClass
objetos (creo) es cuando lanzas una matriz como un objeto o cuando creas un nuevostdClass
objeto desde cero (y, por supuesto, cuando tienesjson_decode()
algo, ¡tonto por olvidar!)En vez de:
$foo = new StdClass(); $foo->bar = '1234';
Harías:
$foo = array('bar' => '1234'); $foo = (object)$foo;
O si ya tenía un objeto stdClass existente:
$foo = (array)$foo; $foo['bar'] = '1234'; $foo = (object)$foo;
También como 1 delineador:
$foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );
fuente
error_reporting(E_STRICT);
enPHP 5.3.15-1~dotdeb.0 with Suhosin-Patch
, no obtengo ningún error o aviso cuando intento establecer una propiedad inexistente en un objeto stdClass. ¿Qué versión de PHP estás usando?Hazlo asi:
$foo = new stdClass(); $foo->{"bar"} = '1234';
ahora intenta:
echo $foo->bar; // should display 1234
fuente
Si desea editar el JSON decodificado, intente obtenerlo como una matriz asociativa en lugar de una matriz de objetos.
$data = json_decode($json, TRUE);
fuente
Yo siempre uso de esta manera:
$foo = (object)null; //create an empty object $foo->bar = "12345"; echo $foo->bar; //12345
fuente
debe utilizar los métodos mágicos __Set y __get. Ejemplo 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]; } }
Por supuesto, no use este ejemplo como este: no hay seguridad en absoluto :)
EDITAR: visto sus comentarios, aquí podría haber 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...'); } } } }
PD: No probé mi código, solo la idea general ...
fuente
No sé si es la versión más nueva de php, pero 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 de guardar realmente obtiene la nueva propiedad
Person Object ( [name] => Ganga [age] => 23 )
fuente
Sí, es posible agregar propiedades dinámicamente a un objeto PHP.
Esto es útil cuando se recibe un objeto parcial de javascript.
Lado JAVASCRIPT:
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 */ } });
Lado PHP:
$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 SÓLO ENVIAR UNA PROPIEDAD DUMMY desde JavaScript que completará en PHP.
fuente