How to add property to object in PHP >= 5.3 strict mode without generating error

PhpClass

Php Problem Overview


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.

Php Solutions


Solution 1 - Php

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' ) );

Solution 2 - Php

Do it like this:

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

now try:

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

Solution 3 - Php

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);

Solution 4 - Php

This is another way:

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

echo $foo->bar; //12345

Solution 5 - Php

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...

Solution 6 - Php

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
    )

Solution 7 - Php

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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRayView Question on Stackoverflow
Solution 1 - PhpWWWView Answer on Stackoverflow
Solution 2 - PhpJM R.View Answer on Stackoverflow
Solution 3 - Phpgen_EricView Answer on Stackoverflow
Solution 4 - PhpRagnarView Answer on Stackoverflow
Solution 5 - PhpBenjamin DuboisView Answer on Stackoverflow
Solution 6 - PhpGangaView Answer on Stackoverflow
Solution 7 - PhpAdrian CumpanasuView Answer on Stackoverflow