objetos - Cómo agregar propiedad a un objeto en PHP>=5.3 modo estricto sin generar error
objetos en php ejemplos (7)
Hazlo asi:
$foo = new StdClass();
$foo->{"bar"} = ''1234'';
ahora intenta:
echo $foo->bar; // should display 1234
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) de 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.
No sé si es la versión más nueva 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 de guardar realmente obtiene la nueva propiedad
Person Object
(
[name] => Ganga
[age] => 23
)
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 de 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 SOLO ENVIAR UNA PROPIEDAD DUMMY de javascript que completará PHP.
Si desea editar el JSON descodificado, intente obtenerlo como una matriz asociativa en lugar de una matriz de objetos.
$data = json_decode($json, TRUE);
Si tiene que 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 stdClass
objetos stdClass
(creo) es cuando lanzas una matriz como un objeto o cuando creas un nuevo objeto stdClass
desde cero (y por supuesto cuando json_decode()
algo - ¡tonto por olvidar!).
En lugar 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 un trazador de líneas 1:
$foo = (object) array_merge( (array)$foo, array( ''bar'' => ''1234'' ) );
Yo siempre uso de esta manera:
$foo = (object)null; //create an empty object
$foo->bar = "12345";
echo $foo->bar; //12345
deberías usar 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 :)
EDIT: 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 ...