155

As we know, creating anonymous objects in JavaScript is easy, like the code below:

var object = { 
    p : "value", 
    p1 : [ "john", "johnny" ]
};

alert(object.p1[1]);

Output:

an alert is raised with value "johnny"

Can this same technique be applied in PHP? Can we create anonymous objects in PHP?

miken32
  • 42,008
  • 16
  • 111
  • 154
Sujit Agarwal
  • 12,348
  • 11
  • 48
  • 79
  • 1
    Note: this is an old question, so the accepted answer is out-of-date. This feature being asked for has now been added to PHP 7. See the answer below by @Rizier123. – Simba Mar 18 '16 at 09:41
  • @Simba - Thanks for pointing it out. Would you like to post an answer on StackOverflow here on this page to help future visitors? – Sujit Agarwal Aug 19 '16 at 05:00
  • 1
    I don't need to; there is already an answer with this info (see below, by @Rizier123). – Simba Aug 19 '16 at 09:17

12 Answers12

244

"Anonymous" is not the correct terminology when talking about objects. It would be better to say "object of anonymous type", but this does not apply to PHP.

All objects in PHP have a class. The "default" class is stdClass, and you can create objects of it this way:

$obj = new stdClass;
$obj->aProperty = 'value';

You can also take advantage of casting an array to an object for a more convenient syntax:

$obj = (object)array('aProperty' => 'value');
print_r($obj);

However, be advised that casting an array to an object is likely to yield "interesting" results for those array keys that are not valid PHP variable names -- for example, here's an answer of mine that shows what happens when keys begin with digits.

Community
  • 1
  • 1
Jon
  • 428,835
  • 81
  • 738
  • 806
  • 1
    can i push multiple valued array also? – Sujit Agarwal Jun 17 '11 at 10:36
  • 2
    @CodingFreak: You can, **but**: if the array contains sub-arrays and you want those as objects as well, you will need to cast every one to object explicitly. – Jon Jun 17 '11 at 10:38
40

It has been some years, but I think I need to keep the information up to date!

Since PHP 7 it has been possible to create anonymous classes, so you're able to do things like this:

<?php

    class Foo {}
    $child = new class extends Foo {};

    var_dump($child instanceof Foo); // true

?>

You can read more about this in the manual

But I don't know how similar it is implemented to JavaScript, so there may be a few differences between anonymous classes in JavaScript and PHP.

miken32
  • 42,008
  • 16
  • 111
  • 154
Rizier123
  • 58,877
  • 16
  • 101
  • 156
  • @risyasin Thanks, updated the answer and put the manual link in it. – Rizier123 Dec 19 '15 at 00:54
  • Marking your answer as correct to keep up with latest changes in php7. Thanks @Rizier123 – Sujit Agarwal Aug 19 '16 at 12:46
  • 9
    This is interesting but it doesn't really address the question, as the OP was asking about a convenient way to initialise an object with various members without creating a class. I am not sure whether anonymous classes in php can be used to do that, and if it can, you didn't explain how. – amh15 May 25 '18 at 13:36
29

Up until recently this is how I created objects on the fly.

$someObj = json_decode("{}");

Then:

$someObj->someProperty = someValue;

But now I go with:

$someObj = (object)[];

Then like before:

$someObj->someProperty = someValue;

Of course if you already know the properties and values you can set them inside as has been mentioned:

$someObj = (object)['prop1' => 'value1','prop2' => 'value2'];

NB: I don't know which versions of PHP this works on so you would need to be mindful of that. But I think the first approach (which is also short if there are no properties to set at construction) should work for all versions that have json_encode/json_decode

Zuks
  • 1,247
  • 13
  • 20
22

Yes, it is possible! Using this simple PHP Anonymous Object class. How it works:

// define by passing in constructor
$anonim_obj = new AnObj(array(
    "foo" => function() { echo "foo"; }, 
    "bar" => function($bar) { echo $bar; } 
));

$anonim_obj->foo(); // prints "foo"
$anonim_obj->bar("hello, world"); // prints "hello, world"

// define at runtime
$anonim_obj->zoo = function() { echo "zoo"; };
$anonim_obj->zoo(); // prints "zoo"

// mimic self 
$anonim_obj->prop = "abc";
$anonim_obj->propMethod = function() use($anonim_obj) {
    echo $anonim_obj->prop; 
};
$anonim_obj->propMethod(); // prints "abc"

Of course this object is an instance of AnObj class, so it is not really anonymous, but it makes possible to define methods on the fly, like JavaScript do.

Mihailoff
  • 577
  • 5
  • 6
  • You can use [create_function](http://php.net/manual/en/function.create-function.php) to emulate anonymous function. – Mihailoff Sep 26 '13 at 14:27
  • I think he just wanted a neat way to initialise a stdClass object with some values. Can you do that with your approach? – amh15 May 25 '18 at 13:38
11

Convert array to object (but this is not recursive to sub-childs):

$obj = (object)  ['myProp' => 'myVal'];
T.Todua
  • 53,146
  • 19
  • 236
  • 237
7

If you wish to mimic JavaScript, you can create a class Object, and thus get the same behaviour. Of course this isn't quite anonymous anymore, but it will work.

<?php 
class Object { 
    function __construct( ) { 
        $n = func_num_args( ) ; 
        for ( $i = 0 ; $i < $n ; $i += 2 ) { 
            $this->{func_get_arg($i)} = func_get_arg($i + 1) ; 
        } 
    } 
} 

$o = new Object( 
    'aProperty', 'value', 
    'anotherProperty', array('element 1', 'element 2')) ; 
echo $o->anotherProperty[1];
?>

That will output element 2. This was stolen from a comment on PHP: Classes and Objects.

kba
  • 19,333
  • 5
  • 62
  • 89
5

Support for anonymous classes has been available since PHP 7.0, and is the closest analogue to the JavaScript example provided in the question.

<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
};

echo $object->p1[1];

The visibility declaration on properties cannot be omitted (I just used var because it's shorter than public.)

Like JavaScript, you can also define methods for the class:

<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
    function foo() {return $this->p;}
};

echo $object->foo();
miken32
  • 42,008
  • 16
  • 111
  • 154
2

Anoynmus object wiki


$object=new class (){


};

dılo sürücü
  • 3,821
  • 1
  • 26
  • 28
1

For one who wants a recursive object:

$o = (object) array(
    'foo' => (object) array(
        'sub' => '...'
    )
);

echo $o->foo->sub;
Jonatas Walker
  • 13,583
  • 5
  • 53
  • 82
1

From the PHP documentation, few more examples:

<?php

$obj1 = new \stdClass; // Instantiate stdClass object
$obj2 = new class{}; // Instantiate anonymous class
$obj3 = (object)[]; // Cast empty array to object

var_dump($obj1); // object(stdClass)#1 (0) {}
var_dump($obj2); // object(class@anonymous)#2 (0) {}
var_dump($obj3); // object(stdClass)#3 (0) {}

?>

$obj1 and $obj3 are the same type, but $obj1 !== $obj3. Also, all three will json_encode() to a simple JS object {}:

<?php

echo json_encode([
    new \stdClass,
    new class{},
    (object)[],
]);

?>

Outputs:

[{},{},{}]

https://www.php.net/manual/en/language.types.object.php

Glorious Kale
  • 1,273
  • 15
  • 25
0

If you want to create object (like in javascript) with dynamic properties, without receiving a warning of undefined property, when you haven't set a value to property

class stdClass {

public function __construct(array $arguments = array()) {
    if (!empty($arguments)) {
        foreach ($arguments as $property => $argument) {
            if(is_numeric($property)):
                $this->{$argument} = null;
            else:
                $this->{$property} = $argument;
            endif;
        }
    }
}

public function __call($method, $arguments) {
    $arguments = array_merge(array("stdObject" => $this), $arguments); // Note: method argument 0 will always referred to the main class ($this).
    if (isset($this->{$method}) && is_callable($this->{$method})) {
        return call_user_func_array($this->{$method}, $arguments);
    } else {
        throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()");
    }
}

public function __get($name){
    if(property_exists($this, $name)):
        return $this->{$name};
    else:
        return $this->{$name} = null;
    endif;
}

public function __set($name, $value) {
    $this->{$name} = $value;
}

}

$obj1 = new stdClass(['property1','property2'=>'value']); //assign default property
echo $obj1->property1;//null
echo $obj1->property2;//value

$obj2 = new stdClass();//without properties set
echo $obj2->property1;//null
fredtma
  • 1,007
  • 2
  • 17
  • 27
-1

Can this same technique be applied in case of PHP?

No - because javascript uses prototypes/direct declaration of objects - in PHP (and many other OO languages) an object can only be created from a class.

So the question becomes - can you create an anonymous class.

Again the answer is no - how would you instantiate the class without being able to reference it?

symcbean
  • 47,736
  • 6
  • 59
  • 94