47

I want to set attribute for a stdClass object in a single statement. I don't have any idea about it. I know the following things

$obj = new stdClass;
$obj->attr = 'loremipsum';

It takes two statements.

$obj = (object) array('attr'=>'loremipsum');

It takes single statement but it is not direct method.

$obj = new stdClass(array('attr'=>'loremipsum'));

It is not working.

Mohammed H
  • 6,880
  • 16
  • 81
  • 127
  • 2
    You cannot do this using `stdClass`. You will need to create your own custom class which has a constructor. – deceze Dec 07 '12 at 10:36

3 Answers3

76
$obj = (object) array(
    'attr'=>'loremipsum'
);

Actually, that's as direct as it's going to get. Even a custom constructor won't be able to do this in a single expression.

The (object) cast might actually be a simple translation from an array, because internally the properties are stored in a hash as well.

You could create a base class like this:

abstract class MyObject
{
    public function __construct(array $attributes = array())
    {
        foreach ($attributes as $name => $value) {
            $this->{$name} = $value;
        }
    }
}

class MyWhatever extends MyObject
{
}

$x = new MyWhatever(array(
    'attr' => 'loremipsum',
));

Doing so will lock up your constructor though, requiring each class to call its parent constructor when overridden.

Ja͢ck
  • 170,779
  • 38
  • 263
  • 309
  • Why you are creating "MyWhatever"? you can directly use the "MyObject" by removing the abstract keyword, right? – Mohammed H Dec 07 '12 at 11:30
  • Sure, if you're okay with having instances of the base class you can remove the abstract keyword :) – Ja͢ck Dec 07 '12 at 11:33
7

Though Ja͢ck gives a good answer, it is important to stress that the PHP interpreter itself has a method for describing how to properly represent an object or variable:

php > $someObject = new stdClass();
php > $someObject->name = 'Ethan';
php > var_export($someObject);
stdClass::__set_state(array(
   'name' => 'Ethan',
))

Interestingly, using stdClass::__set_state fails to create a stdClass object, thus displaying it as such is likely a bug in var_export(). However, it does illustrate that there is no straightforward method to create the stdClass object with attributes set at the time of object creation.

dotancohen
  • 30,064
  • 36
  • 138
  • 197
4
        foreach ($attributes as $name => $value) {
            if (property_exists(self::class, $name)) {
                $this->{$name} = $value;
            }
        }

is cleanest because it will set an arbitrary attribute if you print_r(get_object_vars($obj)) of returned object if attribute does not exist.

Hydtek
  • 161
  • 1
  • 12