93

This has to be simple, but I can't seem to find an answer....

I have a generic stdClass object $foo with no properties. I want to add a new property $bar to it that's not already defined. If I do this:

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

PHP in strict mode complains.

What is the proper way (outside of the class declaration) to add a property to an already instantiated object?

NOTE: I want the solution to work with the generic PHP object of type stdClass.

A little background on this issue. I'm decoding a json string which is an array of json objects. json_decode() generates an array of StdClass object. I need to manipulate these objects and add a property to each one.

4

7 回答 7

146

If you absolutely have to add the property to the object, I believe you could cast it as an array, add your property (as a new array key), then cast it back as an object. The only time you run into stdClass objects (I believe) is when you cast an array as an object or when you create a new stdClass object from scratch (and of course when you json_decode() something - silly me for forgetting!).

Instead of:

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

You'd do:

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

Or if you already had an existing stdClass object:

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

Also as a 1 liner:

$foo = (object) array_merge( (array)$foo, array( 'bar' => '1234' ) );
于 2012-07-23T18:45:45.933 回答
137

Do it like this:

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

now try:

echo $foo->bar; // should display 1234
于 2015-09-15T08:55:00.893 回答
11

If you want to edit the decoded JSON, try getting it as an associative array instead of an array of objects.

$data = json_decode($json, TRUE);
于 2012-07-23T18:57:02.460 回答
5

This is another way:

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

echo $foo->bar; //12345
于 2016-08-17T18:18:40.637 回答
1

you should use magic methods __Set and __get. Simple example:

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

}

Of course, don't use this example as this : no security at all :)

EDIT : seen your comments, here could be an alternative based on reflection and a decorator :

 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 : I didn't test my code, just the general idea...

于 2012-07-23T18:37:53.200 回答
1

I don't know whether its the newer version of php, but this works. I'm using 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();

This is the result. The save method actually gets the new property

    Person Object
    (
       [name] => Ganga
       [age] => 23
    )
于 2015-12-18T07:49:46.940 回答
-8

Yes, is possible to dynamically add properties to a PHP object.

This is useful when a partial object is received from javascript.

JAVASCRIPT side:

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 side:

$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

OR JUST SEND A DUMMY PROPERTY from javascript that you will fill in PHP.

于 2014-07-19T11:53:30.400 回答