70

In PHP, I can specify array literals quite easily:

array(
    array("name" => "John", "hobby" => "hiking"),
    array("name" => "Jane", "hobby" => "dancing"),
    ...
)

But what if I want array of objects? How can I specify object literal in PHP? I.e. in javascript it would be:

[
    {name: "John", hobby: "hiking"},
    {name: "Jane", hobby: "dancing"}
]
5
  • 5
    There is no object literal in PHP.
    – BoltClock
    Commented Mar 10, 2012 at 7:57
  • 1
    @ŠimeVidas, I don't understand your comment. JS objects is associative arrays, but PHP associative arrays are not objects. Also PHP is not ECMAScript language, and PHP is not even JS.
    – Dima Zorin
    Commented Dec 24, 2012 at 15:33
  • @DmitryZorin I see. I thought that PHP associative arrays are objects (like in JavaScript). Commented Dec 24, 2012 at 16:43
  • @ŠimeVidas I understand what you are saying but what you must understand is how the two different langauges are interpreted, which is very different.
    – GriffLab
    Commented Jul 27, 2013 at 6:32
  • 3
    @ŠimeVidas I think TMS was showing how to do it in JavaScript as an illustration. So the question is "how do I do the same in PHP?"
    – Stewart
    Commented Aug 27, 2016 at 17:11

10 Answers 10

100

As BoltClock mentioned there is no object literal in PHP however you can do this by simply type casting the arrays to objects:

$testArray = array(
    (object)array("name" => "John", "hobby" => "hiking"),
    (object)array("name" => "Jane", "hobby" => "dancing")
);

echo "Person 1 Name: ".$testArray[0]->name;
echo "Person 2 Hobby: ".$testArray[1]->hobby;
6
  • 13
    Do note that objects are always passed by reference, arrays are not. So changing an attribute of an object changes it everywhere the object has been assigned. This is not the case for arrays; they remain independent. Commented Mar 18, 2014 at 23:08
  • 1
    @GregoryCosmoHaun Objects are not passed by reference. They are passed by a numeric value called object identifier. Which allows object accessors to find the actual object.
    – Rain
    Commented Nov 14, 2020 at 20:57
  • @Rain What is the difference? An "object identifier" that refers to a particular object is a reference to the object, isn't it? Commented Jan 6, 2021 at 17:15
  • 1
    @Stack-Underflow You can see how these techniques are different here 3v4l.org/hkOcA
    – Rain
    Commented Jan 6, 2021 at 20:10
  • 1
    @Rain the example you linked has a typo that obscures what you were trying to show. Here's a corrected version: 3v4l.org/njjm6. Commented Oct 3, 2022 at 10:37
69

As of PHP 5.4 you can also use the short array syntax:

$json = [
    (object) ['name' => 'John', 'hobby' => 'hiking'],
    (object) ['name' => 'Jane', 'hobby' => 'dancing'],
];
1
  • 3
    excelent, this makes for a lot cleaner scripts
    – David V
    Commented Sep 20, 2014 at 3:31
16

As others have noted, there is no object literal in PHP, but you can "fake" it by casting an array to an object.

With PHP 5.4, this is even more concise, because arrays can be declared with square brackets. For example:

$obj = (object)[
    "foo" => "bar",
    "bar" => "foo",
];

This would give you an object with "foo" and "bar" properties. However, I don't think this really provides much advantage over using associative arrays. It's just a syntax difference.

Consider embracing the uniqueness and "flavor" of all the languages you use. In JavaScript, object literals are all over the place. In PHP, associative arrays are functionally the same as JavaScript object literals, are easy to create, and are well understood by other PHP programmers. I think you're better off embracing this "flavor" than trying to make it feel like JavaScript's object literal syntax.

0
4

Another way would be to use the __set_state() magic method:

$object = stdClass::__set_state (array (
    'height'   => -10924,
    'color'    => 'purple',
    'happy'    => false,
    'video-yt' => 'AgcnU74Ld8Q'
));

Some more on the __set_state() method, where is it coming from and how is it supposed to be used.

1
  • 3
    -1, This would be cool if it worked. However, stdClass does not have a defined __set_state method.
    – Shad
    Commented Mar 18, 2013 at 20:31
4

Although casting as an (object) works fine on a single hierarchical level, it doesn't go deep. In other words, if we want objects at every level, we'd have to do something like:

$foods = (object)[
  "fruits" => (object)["apple" => 1, "banana" => 2, "cherry" => 3],
  "vegetables" => (object)["asparagus" => 4, "broccoli" => 5, "carrot" => 6]
];

However, instead of doing multiple casting as objects, we can wrap the whole thing in a json_encode and json_decode like this:

$foods = json_decode(json_encode([
  "fruits" => ["apple" => 1, "banana" => 2, "cherry" => 3],
  "vegetables" => ["asparagus" => 4, "broccoli" => 5, "carrot" => 6]
]));

That makes sure it's an object at the deepest level.

To answer klewis, you can then access this like:

echo $foods->vegetables->broccoli;

This example would output the number 5.

3
  • Nice solutions, can you provide a simple example with your second option in referencing the value of broccoli in an echo statement?
    – klewis
    Commented Jan 29, 2020 at 12:24
  • 1
    <?php $foods = json_decode(json_encode([ "fruits" => ["apple" => 1, "banana" => 2, "cherry" => 3], "vegetables" => ["asparagus" => 4, "broccoli" => 5, "carrot" => 6] ])); echo $foods->vegetables->broccoli; ?> should output the number 5 Commented Jan 30, 2020 at 14:35
  • by far the best answer on this thread for thoughe coming from a javascript background and want either a single level or deep level approach.
    – klewis
    Commented Jan 30, 2020 at 16:08
2

My way of JavaScript-style object literals in PHP is as follows:

First I create an associative array like this:

$test = array(
  'name' => "test",
  'exists' => true
);

Then I easily make it an object like this:

$test = (object)$test;

Now you can test it:

echo gettype($test); // "object"
echo $test->name; // "test"
0

If you're wanting to define modules in the object literal pattern "like JavaScript", you could do something like this:

$object = (object) [
    'config' => (object) [
        'username' => 'Rob Bennet',
        'email' => '[email protected]'
    ],

    'hello' => function() use(&$object) {
        return "Hello " . $object->config->username . ". ";
    },

    'emailDisplay' => function() use(&$object) {
        return "Your email address is " . $object->config->email;
    },

    'init' => function($options) use(&$object) {
        $object->config = $options;
        $doUsername = $object->hello;
        $doEmail = $object->emailDisplay;
        return $doUsername() . $doEmail();
    }
];

$sayMyInfo = $object->init;

echo $sayMyInfo((object) [
    'username' => 'Logan',
        'email' => '[email protected]'
]);

In this type of modular scenario, I usually opt for the facade pattern, I just like writing my calls thusly:

Module::action()->item;

or

Post::get()->title;

Neither of these patterns make it easy (or even possible sometimes) for testing. But this is just proof of concept. Technically, "no" there is no Object Literal in PHP, but if you're used to JavaScript syntax (which I am more so than PHP), you can fake it and do this. As you can see, it's a lot messier in PHP than in JavaScript.

0

If the json_decode(json_encode( $array )) isn't good for you, then you can use some similar functions like these. Which one is faster, I don't know.

function deep_cast_object( $o ){
  return deep_cast_object_ref( $o );
}

function deep_cast_object_ref( & $o ){

  if( is_array( $o ))
    $o = (object)$o;

  if( is_object( $o ))
    foreach( $o as & $v )
      deep_cast_object_ref( $v );

  return $o;
}

$obj = deep_cast_object(array(
  'Fractal' => array(
    'of'    => array(
      'bad' => 'design',
    ),
  ),
));

var_dump( $obj );
-1

In PHP, you have ro create an instance before you can use a class. Of course you can put the instances into an array later.

-1

Simple solution

$obj = json_decode('{"ape":"kwyjibo"}');
echo $obj->ape;

[output:]
kwyjibo

Then you can wrap it into a function and return your literal object

$obj = literal_object(['key1','val1','key2','val2']);

Not the answer you're looking for? Browse other questions tagged or ask your own question.